home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / sharew / pdpro / expert / rules. < prev   
Encoding:
Text File  |  1994-02-22  |  219.5 KB  |  7,478 lines

  1.  
  2.                   NYACC MEMBERSHIP APPLICATION
  3.               New York Amateur Computer CLub, Inc.
  4.                            PO Box 106
  5.             Church Street Station, New York NY 10008
  6.  
  7.  
  8.          [ ] New Member    [ ] Renewal    Dues are $15.00
  9.                Please make checks payable to NYACC
  10.  
  11. First name:__________________  Last name: _______________________
  12.  
  13. Mailing Address: ________________________________________________
  14.  
  15. City: ___________________ State: _____ Zip: ______ Country: _____
  16.  
  17. Business phone: (___) ___-____          Home phone: (___)___-____
  18.  
  19. What topics would you like covered at club meetings:
  20.  
  21.  
  22.  
  23. Would you like to speak at a club meeting? [ ] yes [ ] no
  24. Topic(s):
  25.  
  26.  
  27.  
  28. Can you help the club? [ ] general   [ ] newsletter  [ ] flea market
  29. [ ] meetings  [ ] user group
  30.  
  31.  
  32.  
  33. Comments:
  34.  
  35.  
  36.  
  37. MZ[ß  ┤!brÇ═-?dâ╛╓F╤·· 0HX┐
  38. [¿ 
  39.          
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.                            AUTOMATA DESIGN ASSOCIATES
  53.  
  54.  
  55.  
  56.                                                           1570 Arran Way
  57.                                                           Dresher, Pa.
  58.                                                           19025
  59.                                                           (215)-646-4894
  60.                                                           December 14,1985
  61.         Dear PD user:
  62.  
  63.              Here's version 1.8 of PD PROLOG. It's better, of course. And 
  64.         now I must ask a favor of you.
  65.  
  66.              The   AAAI   fifth   national   conference   on   artificial 
  67.         intelligence is on August 11 to 15th, 1986 in Philadelphia. Since 
  68.         I live next to Philly,  I'd love to exhibit there. The problem is 
  69.         that  the rate is $2200 for a 10' x 10' booth,  with a $600  rate 
  70.         for publishers.
  71.  
  72.              I  am  appealing to the coordinator of the  conference,  Ms. 
  73.         Claudia   Mazzetti,   for  a  publishers  rate  break  with   the 
  74.         justification  of my contribution to the public  domain.  I  have 
  75.         sent  to Ms.  Mazzetti a financial statement which shows  clearly 
  76.         that  I  cannot afford the standard rate.  Ms.  Mazzetti was  not 
  77.         particularly   impressed  with  my  request,   but  perhaps  some 
  78.         substantiation of my contribution will change her mind.
  79.  
  80.              I  therefore  request that you  write  Ms.  Mazzetti  before 
  81.         February  at the below address,  and inform her of what I've done 
  82.         for mankind, the Byte readership, etc:
  83.  
  84.                               Ms. Claudia Mazzetti
  85.                               Director, AAAI-86
  86.                               445 Burgess Drive
  87.                               Menlo Park, CA 94025-3496
  88.  
  89.                                 Sincerely yours,
  90.  
  91.  
  92.                                    Bob Morein
  93.                               Author, A.D.A. PROLOG
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.                      A.D.A PROLOG Documentation Version 1.80
  111.                   for the Educational and Public Domain Versions
  112.  
  113.                                   December 14, 1985
  114.  
  115.               Copyright Robert Morein and Automata Design Associates
  116.  
  117.                                  1570 Arran Way
  118.                                Dresher, Pa. 19025
  119.  
  120.                                  (215)-646-4894
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.                                       News
  172.  
  173.              Release 1.80 is further debugged. There are no new features. 
  174.         However,  there  are  some new sample programs by  Tom  Sullivan. 
  175.  
  176.              There  is  also a very interesting natural language  parsing 
  177.         system by Lou Schumacher of Future Dimensions in directory "ATN". 
  178.         Lou's system, known as an augmented transition network parser, is 
  179.         very well documented,  since the paper he wrote on the subject is 
  180.         also included.  You'll need Volkswriter to print it out, but it's 
  181.         readable as is.  The system requires ED PROLOG to run,  since  it 
  182.         makes use of the grammar rule syntax.
  183.  
  184.              Simon   Blackwell's   "PIE"  Truth  Maintenance  System   is 
  185.         presented in revised, debugged, and enlarged form. This system is 
  186.         found  in  the  directory  "expert"  and  augments  the  strictly 
  187.         deductive  capabilities  of raw Prolog with additional  forms  of 
  188.         reasoning.  PIE  has a syntax that resembles colloquial  English. 
  189.         Wait till you see the backwards quote marks!
  190.  
  191.              The predicates "batch" and "nobatch" are introduced to allow 
  192.         execution  of batch files without confusing messages and  prompts 
  193.         appearing on the screen. I've put one in Simon's "KOPS" file.
  194.  
  195.  
  196.  
  197.                                 Copyright Notice
  198.  
  199.              The  public domain PD PROLOG system has been contributed  to 
  200.         the  public domain for unrestricted use with one  exception:  the 
  201.         object  code  may not be  disassembled  or  modified.  Electronic 
  202.         bulletin  boards  and SIG groups are urged to aid in giving  this 
  203.         software the widest possible distribution.
  204.  
  205.              This documentation may be reproduced freely,  but it may not 
  206.         be  included in any other documentation without the permission of 
  207.         the author.
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.                                   Introduction
  238.                 
  239.         We  are pleased to present the third major version of PD  PROLOG, 
  240.         version 1.7.  Version 1.7 continues to refine "problems" and adds 
  241.         the  entertaining  feature of IBM PC video  screen  support.  The 
  242.         memory requirements are somewhat greater than the original, since 
  243.         it   is  uses  the  large  memory  model.   It   compensates   in 
  244.         thoroughness.  The memory requirement is about 210K bytes of TPA, 
  245.         and it will benefit from up to 253k bytes. The availalble 
  246.         workspace is 100K bytes.
  247.  
  248.         We  hope  that you'll get some fun out of this  PROLOG.  It  will 
  249.         afford  you exposure to THE fifth generation language at the cost 
  250.         only  of  some  intellectual  effort.  The  motive  is  perfectly 
  251.         explicable:  We  want you to think of Automata Design  Associates 
  252.         for  fifth  generation  software.  It also gives us a  nice  warm 
  253.         feeling.
  254.  
  255.         The  minimum  memory  requirement is 200 k of  transient  program 
  256.         area,  plus  whatever  space is needed to execute  programs  from 
  257.         within PROLOG.  DOS or MSDOS 2.0 are required.  The program  does 
  258.         not  require  IBM PC compatibility to run,  although  the  screen 
  259.         access routines do require compatibility.
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.                      Products by Automata Design Associates
  304.  
  305.              Automata  Design  Associates  specializes  in  software  for 
  306.         artificial  intelligence  and  robotic  applications.   A  PROLOG 
  307.         language  system is available in various configurations.  A  LISP  
  308.         interpreter will be introduced in March of 1985.
  309.  
  310.  
  311.              There  are five versions of PROLOG available  from  Automata 
  312.         Design  Associates.  All  of  them run under the MSDOS  or  PCDOS 
  313.         operating systems. Other environments will be supported soon.
  314.  
  315.  
  316.              .Public Domain PROLOG
  317.  
  318.         This  serves to further the general awareness of the public about 
  319.         PROLOG.  It  also is an excellent adjunct to anyone learning  the 
  320.         language.  Most  of  the core PROLOG described  by  Clocksin  and 
  321.         Mellish  in  the book Programming In  PROLOG  is  implemented.  A 
  322.         complete  IBM PC video screen support library is included in this 
  323.         and  all other A.D.A.  prologs.  Trace predicates are  not.  This 
  324.         version is available from us for $10.00 postage paid.
  325.  
  326.  
  327.              .Educational PROLOG
  328.  
  329.         At  extremely modest cost this affords an educational institution 
  330.         or  individual  a  PROLOG  system  which  provides  the   maximum 
  331.         available  programming  area  available  within  the  8086  small 
  332.         programming model.  Tracing,  a debugging aid,  allows monitoring 
  333.         a program as it runs.  User settable spy points selectively allow 
  334.         this.  Exhaustive  tracing  is also  available.  I/O  redirection 
  335.         gives some file ability.
  336.  
  337.              An  "exec"  function allows the execution of  a  program  or 
  338.         editor  from  within  PROLOG,  thus  encouraging  an  interactive 
  339.         environment.
  340.  
  341.              An  "interrupt"   menu is added,  permitting the control  of 
  342.         tracing, toggling the printer, and screen printing.
  343.  
  344.              Definite clause grammar support is now included.
  345.              
  346.              The cost of Educational PROLOG is $29.95.
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.              .FS PROLOG
  370.  
  371.              A  small  increment  in price adds full random  access  file 
  372.         capability. Character and structure I/O are allowed.
  373.  
  374.              The  "asserta and "assertz" predicates are expanded and work 
  375.         with a clause indexing ability.  One can assert clauses  anywhere 
  376.         in the database under precise pattern matching control. 
  377.  
  378.              A tree structured lexical scoping system and floating  point 
  379.         arithmetic are other enhancements.
  380.  
  381.              The cost of FSM PROLOG is $49.95
  382.  
  383.  
  384.  
  385.              .VMI PROLOG -- Virtual Memory (Replaces type VMS)
  386.  
  387.  
  388.              At reasonable cost the addition of virtual memory gives  an 
  389.         expansion of capabilities of an order of magnitude. 
  390.  
  391.              The  database on disk is treated transparently.  No  special 
  392.         provisions  need  be  made  by the  user.  Virtual  and  resident 
  393.         databases  may be mixed.  A unique updating algorithim  preserves 
  394.         the format of the database as typed by the user while making only 
  395.         those changes necessary to make it equivalent to the database  in 
  396.         central memory.
  397.  
  398.              The cost of VMI PROLOG is $99.95
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.              .VML PROLOG Large model Virtual Memory System
  436.  
  437.              A.D.A.  PROLOG is a remarkable fifth generation developement 
  438.         tool  for  the  implementation  of  intelligent  strategies   and 
  439.         optimized  control.  It  is both the kernel for  applications  of 
  440.         virtually  unlimited scope and a sophisticated developement  tool 
  441.         that multiplies the productivity of the programmer many times. 
  442.  
  443.              With  a  cost/performance ratio exceeding that of any  other 
  444.         product  and  a  compatibility  insured  by  compliance  to   the 
  445.         Edinburgh syntax, performance is enhanced by numerous extensions, 
  446.         many of them invisible to the user.
  447.  
  448.              A quick overview of some of the features discloses:
  449.  
  450.              1)  Invisible  compilation  to  a  semantic  network 
  451.              preserves the flexibility of the interpreted mode and 
  452.              the speed of a compiler.
  453.  
  454.              The  programmer can compile and recompile any portion 
  455.              of a module at any time.  The edit/compile/test cycle 
  456.              is short and free of strain. An interface is provided 
  457.              to an editor of choice.
  458.  
  459.  
  460.              2) Floating point arithmetic with a full  complement 
  461.              of  input  and  output  methods,  transcendental  and 
  462.              conversion functions.
  463.  
  464.  
  465.              3)  Virtual  memory.  Module  size  and  number  are 
  466.              unrestricted,   with  a  total  capacity  of  several 
  467.              hundred megabytes.  Resident and virtual modules  may 
  468.              be co-resident. Compilation is incremental. The cache 
  469.              algorithim  is  sophisticated.  Changes made  in  the 
  470.              database can be updated to disk by a single command.
  471.  
  472.  
  473.              4) A powerful exec function and acceptance of  stream 
  474.              input make  integration into  applications practical.
  475.  
  476.  
  477.              5)  Global polymorphic variables  retain  information 
  478.              that  would  otherwise  require  the  "assertion"  of 
  479.              facts.
  480.  
  481.  
  482.              6)  A  quoted  variable class,  borrowed  from  LISP, 
  483.              permits  referencing variables as objects as well  as 
  484.              by value.
  485.  
  486.              7) Multidimensional arrays,  dynamically created  and 
  487.              destroyed,  efficiently  store numeric and nonnumeric 
  488.              structures. Arrays are ideal for representing spatial 
  489.              and ordinal relationships.
  490.              8)  Debugging facilities let you see your program run 
  491.              without any additional generation steps.
  492.  
  493.  
  494.              9)   Totally   invisible  and   incremental   garbage 
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.              collection.   There   is  NEVER  any  wait  for  this 
  502.              function.
  503.  
  504.  
  505.              10)  A  tree  structured,   dynamically  configurable 
  506.              lexical scoping system. The work of many  programmers 
  507.              can  be coupled together in the form of libraries and 
  508.              nested domains. 
  509.  
  510.              Each lexically scoped domain is a hidden space  which 
  511.              communicates  with the parent domain via exports  and 
  512.              imports. Domains can be linked together under program 
  513.              control to achieve any desired configuration.
  514.  
  515.  
  516.              11) The Grammar Rule Notation is an integral feature.
  517.  
  518.  
  519.              12) Keyword redefinition makes porting code easy.
  520.  
  521.  
  522.         The  cost  of this system is $200 for the MSDOS version.
  523.  
  524.  
  525.  
  526.         .VMA PROLOG Large model Virtual Memory System
  527.  
  528.         This  system  has  additional forms of  virtual  memory.  It  was 
  529.         intended  for  deep  reasoning  problems.  Contact  us  for  more 
  530.         information.
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.                                  Upgrade Policy
  568.  
  569.              Half the cost of any A.D.A. PROLOG system may be credited to 
  570.         the purchase of a higher level version.      The full cost of VMS 
  571.         prolog  may  be  applied to the purchase of VMI  or  VML  PROLOG. 
  572.         Updates to a particular level product vary from $15.00 to $35.00.
  573.  
  574.  
  575.                                 Run-time Packages
  576.  
  577.              Software  developers wishing to integrate an A.D.A.  product 
  578.         into  their  system  should inquire  about  specialized  run-time 
  579.         packages available at reasonable cost.
  580.  
  581.  
  582.  
  583.                               Technical Information
  584.  
  585.              Technical information may be obtained at (215) - 646- 4894
  586.  
  587.              Perhaps we can answer the following questions in advance:
  588.  
  589.              There is no support for:  APPLE II, Atari, Commodore, or  
  590.         CPM 80 .  Other machines from these manufactures may be supported 
  591.         in the future.
  592.  
  593.              The MSDOS products are available on 5" and 8" diskettes.
  594.  
  595.  
  596.  
  597.                               To Place Your Order:
  598.  
  599.              You may place your order at the following number:
  600.  
  601.                         (215)-646-4894   - day and night.
  602.  
  603.  
  604.  
  605.                                      Returns
  606.  
  607.              The  software may be returned within 30 days of purchase for 
  608.         a full refund.  This applies whether or not the software has been 
  609.         used.  We do ask that manuals, disks and packaging be returned in 
  610.         excellent condition.
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.                                   Installation
  634.  
  635.              You will need an IBM PC compatible machine with a minimum of 
  636.         256 kbytes of memory. ED PROLOG benefits from up to 245 kbytes of 
  637.         program  memory (TPA).  This means in practice that a machine with  320 
  638.         kbytes of memory is optimal for ED PROLOG.
  639.  
  640.              To  determine the amount of TPA your machine  has,  run  the 
  641.         "chkdsk" program which is supplied with DOS. The last line reads:
  642.  
  643.                                 XXXXXX bytes free
  644.  
  645.         where XXXXXX is a six digit number.
  646.  
  647.         If  this  number  is greater than 200000,  ED  PROLOG  will  have 
  648.         reduced workspace.  If it's over 245000,  the amount of memory is 
  649.         optimal. If this is not the case, there are two possibilities:
  650.  
  651.         1) The machine doesn't have enough memory.
  652.  
  653.         2)  Something  else is removing memory from TPA,  such as  a  co-
  654.         resident  program,  a  ramdisk,  a large dos driver,  or a  large 
  655.         number of file or disk buffers.
  656.  
  657.         If  you're  short of memory,  make sure that no  other  programs, 
  658.         ramdisks,  or drivers besides DOS are running in the machine. You 
  659.         may find it helps to eliminate (by renaming) the config.sys  file 
  660.         when you intend to run ED PROLOG.
  661.  
  662.  
  663.                       How to run the Demonstration Programs 
  664.                         without Knowing What You're Doing
  665.  
  666.              We strongly advise that you purchase the book Programming in 
  667.         PROLOG by Clocksin and Mellish,  publisher Springer Verlag, 1981. 
  668.         For  the  impatient we give some advice.  Type the  demonstration 
  669.         program you wish to run.  There must be at least one entry  point 
  670.         within  the  program.  
  671.  
  672.         Note:  Please  understand that these are demonstrations programs. 
  673.         Regarding  user  interface,  they are poorly  written.  You  will 
  674.         probably have to read Clocksin and Mellish to appreciate that the 
  675.         following examples of input are not equivalent: "yes." , "yes" .
  676.  
  677.  
  678.         The animals program - "animal"
  679.          
  680.              Most  of the examples require C & M for  comprehension.  The 
  681.         program "animals", however, can be appreciated by anyone. It is a 
  682.         traditional   example of an expert system.
  683.              
  684.              We had hoped to include the animals program on disk,  but we 
  685.         have  found  to  our  dismay that the version which  we  used  is 
  686.         allegedly copyrighted by the implementors of PROLOG 86.  Don't be 
  687.         surprised - even "happy birthday" is copyrighted.  We will simply 
  688.         point out that the November '84 issue of Robotics Age included  a 
  689.         version  of  the  animals game,  which you can,  at the  risk  of 
  690.         copyright infringement,  type in.  There is only one change  that 
  691.         need  be  made.  The "concat" function used in that  program  has 
  692.         arguments of the form:
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.                       concat( [atom1, atom2,...], result ).
  701.  
  702.         In order to make the concat definition more closely resemble that 
  703.         of  "name",  which  is  described by Clocksin  and  Mellish,  the 
  704.         argments have been reversed:
  705.  
  706.                       concat( result, [atom1, atom2,...] )
  707.  
  708.         Assuming  that you have typed in the program and made the  change 
  709.         just noted, the following steps are required to run it:
  710.              
  711.              Run the prolog.exe file.  The prompt "?-" will appear.  Type 
  712.         "consult( 'animals' ).<CR>".  Here <CR> indicates you are to type 
  713.         a  carriage  return.  The PROLOG system will load  "animals"  and 
  714.         compile  it into an internal form.  When the "?-" prompt  appears 
  715.         PROLOG is ready to run the "animals" guessing game. The object of 
  716.         the program is to deduce the animal you are thinking of. To start 
  717.         it  off  type  "help.<CR>".  PROLOG  will  respond  by  asking  a 
  718.         question. 
  719.              Because of the way the animals program is written,  you must 
  720.         respond in a rigid format.  You may type "yes<CR>",  "no<CR>", or 
  721.         "why<CR>". 
  722.              Eventually the program will terminate with either a guess as 
  723.         to what animal you are thinking of,  or a remark that the  animal 
  724.         is  not within its domain of knowledge.  The program has learned, 
  725.         however.  You  may  run  the  program again to  see  what  effect 
  726.         additional knowledge has on the program's behavior. 
  727.  
  728.              The program fragment "console" shows how you may improve the 
  729.         console input routines of any of these programs.
  730.              
  731.  
  732.         The Hematology Diagnosis Program - "hemat"
  733.  
  734.              Although  the  logical structure is not as sophisticated  as 
  735.         that of "animals", it is interesting for several reasons:
  736.  
  737.              1)  The  program  evaluates numerical data to  arrive  at  a 
  738.         diagnosis.
  739.  
  740.              2) Although inaccurate, it demonstrates that useful question 
  741.         answering systems are not difficult to write in PROLOG.
  742.  
  743.              3)  There  are  some mistakes in  the  program,  which  only 
  744.         slightly impede its usefulness. 
  745.  
  746.              This  program  uses  structure  input.  Terminate  all  your 
  747.         answers with a period, as in "y.<CR>", or "no.<CR>".
  748.         The starting point is "signs.<CR>".  PROLOG will prompt  you 
  749.         for  signs  of  anemia.  The  program attempts  to  diagnose  two 
  750.         varieties of a hemolytic anemia.
  751.              The program could use a good working over by a  hematologist 
  752.         and we would be delighted to collaborate.
  753.  
  754.  
  755.         Prime Number Generator - "sieve"
  756.  
  757.              This  program demonstrates that anything can be programed in 
  758.         PROLOG if one tries hard enough.  Asking the  question   
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.           "primes( 50, L ).<CR>" causes a list of prime numbers less than 
  766.         50  to be printed out.  "Sieve" is heavily recursive and  quickly 
  767.         exhausts the stack space of the small model interpreters.
  768.  
  769.  
  770.         Grrules
  771.  
  772.              This  is  an  example  of the use  of  the  definite  clause 
  773.         grammer  notation.  PD  PROLOG  does not  have  this  translation 
  774.         facility,  but ED PROLOG and  all of our other versions do. It is 
  775.         possible  to  perform  the  translations  by  hand  if  you  have 
  776.         thoroughly  read  C  & M.  Then you would have  the  pleasure  of 
  777.         asking:
  778.  
  779.                  ?-sentence( X, [every,man,loves,a,woman], [] ).
  780.  
  781.         and  having the meaning elucidated as a statment in the predicate 
  782.         calculus.
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.                                Special Offer  # 1
  832.  
  833.              For  some  inexplicable reason,  demonstration programs  are 
  834.         hard to come by. We are too busy writing PROLOG fill this gap. We 
  835.         will  reward the contribution of "cute" sample programs with  the 
  836.         following:
  837.  
  838.              1) A free  copy of type VMI virtual memory PROLOG
  839.  
  840.              2) The sample program will be published as an intact file 
  841.              together with whatever comments or advertisments the author
  842.              may see fit to include, on our distribution disks. 
  843.  
  844.              3) Exceptional contributions may merit a copy of type VML 
  845.              large  model virtual memory PROLOG which now incorporates  a 
  846.              UNIX1 style tree structured domain system.
  847.  
  848.  
  849.                                 Special Offer # 2
  850.  
  851.  
  852.              If  you are a hardware manufacturer and would like a  PROLOG 
  853.         language  for your system,  the solution is simple.  Just send us 
  854.         one  of  your machines!  Provided your system  implements  a  "C" 
  855.         compiler, it will be ported in no time flat.
  856.  
  857.  
  858.         ______
  859.              1. Trademark of AT & T.
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.                          Writing Programs For ED PROLOG
  898.  
  899.              You do not type in programs at the "?-" prompt.  There is no 
  900.         built-in  editor.  The command "consult( user )" is accepted  but 
  901.         does not cause PROLOG to enter an editing mode.  We feel that the 
  902.         most universally acceptable editing method is for the user to use 
  903.         a text editor of choice,  which can be invoked from within PROLOG 
  904.         by the "exec" predicate.
  905.  
  906.              Use  Wordstar  or your customary editor to write a  program. 
  907.         Then  run  PD  PROLOG and use the consult function  to  load  the 
  908.         program.
  909.  
  910.              In  all  cases except PD PROLOG,  you can  run  your  editor 
  911.         without leaving PROLOG by use of the "exec" predicate.
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.                              Running the Interpreter
  964.  
  965.         COMMANDS: Give commands in lower case.
  966.  
  967.         TO RUN:
  968.              Invoke PROLOG.EXE. After the "?-" prompt appears,
  969.                type "consult( <filename><CR> )", where <filename> is the 
  970.                desired database.
  971.              To exit, type "exitsys.<CR>"
  972.  
  973.         TO ENTER A FACT:
  974.              Don't do it except with the "assert" predicates. This is the 
  975.              most  frequently misunderstood aspect of A.D.A.  Prolog.  If 
  976.              you want to enter a bunch of facts,  put them in a file  and 
  977.              "consult" them using the "consult" predicate.
  978.  
  979.         TO ASK A QUESTION:
  980.              At the prompt, type "<expression>.<CR>", where 
  981.              <expression>  is  a  question as described by  Clocksin  and 
  982.              Mellish. Be sure to terminate the question with a period.
  983.              The question may be up to 500 characters long.
  984.  
  985.         TO INPUT A STRUCTURE AT THE KEYBOARD:
  986.              The structure may be up to 500 characters in length. Be sure 
  987.              to terminate with a period.
  988.  
  989.         TO ASK FOR ANOTHER SOLUTION:
  990.              If a solution has been provided, the PROLOG interpreter will 
  991.              ask  "More?  (Y/N):".  Only  if  a "y"  is  typed  will  the 
  992.              interpreter perform a search.
  993.  
  994.         TO ABORT A SEARCH:
  995.              Simply   type   the  escape  key.   The   interpreter   will      
  996.              respond  with  "Interrrupted.",  and return to  the  command      
  997.              prompt.
  998.  
  999.         TO LOAD ANOTHER DATABASE:
  1000.              Type  "consult(<filename>).<CR>" The file name must have the 
  1001.              extension  ".PRO".  It  is  not  necessary  to  include  the 
  1002.              extension in the argument of consult. The file name as given 
  1003.              must not be the same as a predicate name in the file or  any 
  1004.              file which will be loaded.
  1005.  
  1006.         TO TRACE:
  1007.              When the system displays the prompt "?-", type "trace.<CR>".  
  1008.              The display will likely move too rapidly for you to read. To 
  1009.              stop the display,  type Control S.  To restart the  display, 
  1010.              type  Control S.  To turn the trace      display  off,  type 
  1011.              "notrace<CR>"  at  the  prompt  "?-".   The  interrupt  menu 
  1012.              contains  additional  options,  such  as sending  all  trace 
  1013.              output to a file, as well as display at the console.
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.         TO INTERRUPT A PROGRAM:
  1030.              See  the  section  entitled  "The  Interrupt  Menu"  for   a 
  1031.              description  of the flexible options.  Basically,  one types 
  1032.              ESC  to terminate a program,  while Control V or  Control  I 
  1033.              interrupt a program. 
  1034.  
  1035.         TO RECONSULT A FILE:
  1036.              The   predicate  "recon"  is  identical  to  the   Edinburgh 
  1037.              predicate "reconsult."
  1038.  
  1039.         TO REMOVE A DATABASE:
  1040.              Type "forget(<filename>).<CR>"
  1041.  
  1042.         TO EXIT TO THE OPERATING SYSTEM:
  1043.              Type "exitsys.<CR>"
  1044.  
  1045.              The system is totally interactive; any commands the operator 
  1046.         gives  are and must be valid program statements.  Statements must 
  1047.         terminate with a period.      All commands which take a file name 
  1048.         also  accept a path name.  Any name which is not a  valid  PROLOG 
  1049.         atom (refer to C & M) must be enclosed in single quotes. Thus one 
  1050.         could say
  1051.  
  1052.              consult( expert )
  1053.  
  1054.         but one would need single quotes with
  1055.  
  1056.              consult( 'b:\samples\subtype\expert' ).
  1057.  
  1058.  
  1059.         To exit the system, type "exitsys.<CR>"
  1060.  
  1061.         Atoms  may contain MSDOS pathnames if they are enclosed by single 
  1062.         quotes, ie.,  '\b:\samples\animal' .
  1063.  
  1064.         You may consult more than one file at a time.  However, all names 
  1065.         are public and name conflicts must be avoided. The order in which 
  1066.         modules are loaded may,  in cases of poor program design,  affect 
  1067.         the behavior.
  1068.  
  1069.  
  1070.  
  1071.                              Command Line Arguments
  1072.  
  1073.              ED and PD PROLOG accept one command line argument,  which is 
  1074.         the name of a "stream" which replaces the console for input.  The 
  1075.         "stream"  in  MSDOS is a pipe or file which supplies input  until 
  1076.         end-of-file is reached. Control then reverts back to the console. 
  1077.         To avoid noisy parser error messages when end-of-file is reached, 
  1078.         the  last command in the file should be "see( user )." See  Simon 
  1079.         Blackwell's PIE program for an example of this.
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.                                A Reference of Note
  1096.  
  1097.  
  1098.              With  minor  exceptions,  the syntax is a superset  of  that 
  1099.         described  by  Clocksin and Mellish in the  book  Programming  in 
  1100.         Prolog by W.F.  Clocksin and C.S.  Mellish, published by Springer 
  1101.         Verlag in Berlin, Heidelberg, New York, and Tokyo. We shall refer 
  1102.         to this book as "C & M".
  1103.  
  1104.  
  1105.              There   are  very  few   syntactical   differences,   mostly 
  1106.         unrecognized and/or minor.
  1107.              When  an operator is declared using the "op" statement,  the 
  1108.         operator must be enclosed in single quotes in the "op"  statement 
  1109.         itself,  if  it would not otherwise be a legal Edinburgh functor. 
  1110.         Subsequently,  however,  the parser will recognize it for what it 
  1111.         is,  except  in  the "unop" statement,  where it  must  again  be 
  1112.         enclosed in single quotes.
  1113.  
  1114.              Variable numbers of functor paramaters are supported.
  1115.  
  1116.              A  goal  may be represented by a  variable,  which  is  less 
  1117.         restrictive  than  the  C  &  M requirement  that  all  goals  be 
  1118.         functors.  The  variable must be instantiated to a  functor  when 
  1119.         that goal is pursued.
  1120.  
  1121.              Rules which appear inside other expressions must be enclosed 
  1122.         in  parenthesis  if  the "," operator is to be  recognized  as  a 
  1123.         logical connective.
  1124.  
  1125.              All  infix  operators described by C & M,  and user  defined 
  1126.         infix,  prefix, and postfix operators with variable associativity 
  1127.         and precedence are supported exactly as in C & M.
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.                          The Built In Predicate Library
  1162.  
  1163.                         Available Operators in PD and ED PROLOG
  1164.  
  1165.  
  1166.         Column 1 gives the function symbol. 
  1167.  
  1168.         Column 2 gives the precedence. The range of precedence is 1 to 255.
  1169.         A zero in the precedence column indicates the symbol is parsed as 
  1170.         a functor, and precedence is meaningless in this case.
  1171.  
  1172.         Column 3 gives the associativity. 
  1173.         A zero in the associativity column indicates the symbol is parsed
  1174.         as a functor, and associativity is meaningless in this case.
  1175.  
  1176.         Column 4 indicates which version the function is available in. 
  1177.         Unless otherwise noted, the function is available in all versions.
  1178.         Nonstandard predicates are indicated by "NS".
  1179.  
  1180.  
  1181.         op/pred      precedence    associativity         availability
  1182.  
  1183.         "!"             0             0
  1184.         "|"             0             0
  1185.         "="             40,           XFX                   
  1186.         "=="            40,           XFX                   
  1187.         "\\="           40,           XFX                   
  1188.         "\\=="          40,           XFX       
  1189.         "/"             21,           YFX       
  1190.         "@="            40,           XFX       
  1191.         ">="            40,           XFX       
  1192.         "=<"            40,           XFX       
  1193.         ">"             40,           XFX       
  1194.         "<"             40,           XFX       
  1195.         "-"             31,           YFX        
  1196.         "*"             21,           YFX
  1197.         "+"             31,           YFX
  1198.         "=.."           40,           XFX
  1199.         "-->"           255,          YFY       (not  in  PD PROLOG)
  1200.         "?-"            255,          FY  
  1201.               
  1202.  
  1203.  
  1204.         "arg"           0,            0,                                   
  1205.         "asserta"       0,            0,                                   
  1206.         "assertz"       0,            0,                                   
  1207.         "atom"          0,            0,                                   
  1208.         "atomic"        0,            0,                                   
  1209.         "batch"         0,            0
  1210.         "clause"        0,            0,                                   
  1211.         "clearops"      0,            0,                                   
  1212.         "cls"           0,            0,       NS
  1213.         "concat"        0,            0,                                   
  1214.         "consult"       8,            FX,                                  
  1215.         "crtgmode"      0,            0,       NS
  1216.         "crtset"        0,            0,       NS
  1217.         "curset"        0,            0,       NS
  1218.         "curwh"         0,            0,       NS
  1219.         "debugging      0,            0,                                   
  1220.         "dir"           0,            0,                                   
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.         "display"       0,            0,                                   
  1228.         "dotcolor"      0,            0,       NS
  1229.         "drawchar"      0,            0,       NS
  1230.         "drawdot"       0,            0,       NS
  1231.         "drawline"      0,            0,       NS
  1232.         "exec"          0,            0,                                   
  1233.         "exitsys"       0,            0,       NS                          
  1234.         "forget"        0,            0,       NS                          
  1235.         "functor"       0,            0,                                   
  1236.         "get0"          8,            FX,                                  
  1237.         "integer"       0,            0,                                   
  1238.         "is"            40,           XFX,                                 
  1239.         "listing"       0,            0,                                   
  1240.         "memleft"       0,            0,      NS
  1241.         "mod"           11,           XFX,                                 
  1242.         "name"          0,            0,                                   
  1243.         "nl"            0,            0,                                   
  1244.         "nodebug"       0,            0,       (not in PD PROLOG)
  1245.         "nonvar"        0,            0,                                   
  1246.         "nospy"         50,           FX,      (not in PD PROLOG)
  1247.         "not"           60            FX                                   
  1248.         "notrace"       0,            0,       (not in PD PROLOG)
  1249.         "op"            0,            0,                                   
  1250.         "popoff"        0,            0,       NS
  1251.         "popoffd"       0,            0,       NS
  1252.         "popon"         0,            0,       NS
  1253.         "popond"        0,            0,       NS
  1254.         "print"         0,            0,                                   
  1255.         "prtscr"        0,            0,       NS
  1256.         "put"           0,            0,                                   
  1257.         "ratom"         0,            0,                                   
  1258.         "read"          0,            0,                                   
  1259.         "recon"         0,            0, (Note: this is "reconsult")
  1260.         "repeat"        0,            0,                                   
  1261.         "retract"       0,            0                                    
  1262.         "rnum"          0,            0,                                   
  1263.         "see"           0,            0,       
  1264.         "seeing"        0,            0,       
  1265.         "seen"          0,            0,       
  1266.         "skip"          0,            0,       (not in PD PROLOG)
  1267.         "spy"           50,           FX,      
  1268.         "tab"           0,            0,                                   
  1269.         "tell"          0,            0,       
  1270.         "telling"       0,            0,       
  1271.         "told"          0,            0,       
  1272.         "trace"         0,            0,       (not in PD PROLOG)
  1273.         "true"          0,            0,                                   
  1274.         "unop"          0,            0,                                   
  1275.         "var"           0,            0,                                   
  1276.         "write"         0,            0,                                   
  1277.                         Description of the Modifications.
  1278.              
  1279.  
  1280.         I/O Redirection
  1281.  
  1282.         I/O  redirection is a feature described by Clocksin and  Mellish. 
  1283.         The predicates "see",  "seeing",  "seen",  "tell", "telling", and 
  1284.         "told" are used to select the streams used for input and output. 
  1285.  
  1286.              The  predicates  "seen" and "told" require as arguments  the 
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.         name of the stream that is to be closed.  This enables the system 
  1294.         to  remember the indices of several streams and switch  back  and 
  1295.         forth between them.
  1296.  
  1297.              The  predicate "batch",  when inserted at the beginning of a 
  1298.         stream file, has the following properties:
  1299.  
  1300.              1)  The normal prompt,  "?-",  and advisory messages do  not 
  1301.              appear at the screen.
  1302.  
  1303.              2)  It is self cancelling if the input stream is  reassigned 
  1304.              to the console.
  1305.  
  1306.              3) It may also be cancelled by the predicate "batch".
  1307.  
  1308.  
  1309.  
  1310.         call( <goal> )
  1311.  
  1312.              The  predicate as defined in C & M is obsolete.  The purpose 
  1313.         was  to permit a goal search where the goal name was  a  variable 
  1314.         instantiated  to  some functor name.  A.D.A.  permits writing  of 
  1315.         goals with such names,  so the mediation of the "call" clause  is 
  1316.         no longer necessary.
  1317.  
  1318.              The  "call"  predicate  may  be  trivially  implemented  for 
  1319.         compatibility with the PROLOG definition
  1320.  
  1321.                                  call( X ) :- X.
  1322.  
  1323.  
  1324.  
  1325.         clause
  1326.  
  1327.              The  function  clause(  X,  Y ) has the  new  optional  form 
  1328.         clause(  X,  Y,  I  ).  If the third variable is written,  it  is 
  1329.         instantiated  to the current address of a clause in  memory.  The 
  1330.         only  use of the result is with succeeding assertfa and  assertfz 
  1331.         statements.
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.         debugging
  1360.  
  1361.              "Debugging"  prints a list of the current  spypoints.  After 
  1362.         each name a sequence of numbers may appear, indicating the number 
  1363.         of  arguments that is a condition of the trace.  The  word  "all" 
  1364.         appears  if  the  number of arguments is not a condition  of  the 
  1365.         trace.
  1366.  
  1367.         op( <prec>, <assoc>, <functor> )
  1368.  
  1369.              Defines  the  user  definable  grammar  of  a  functor.  The 
  1370.         definition conforms to that in C & M. We mention here a minor but 
  1371.         important point.  If <functor> is not a valid PROLOG atom it must 
  1372.         be   enclosed  in  single  quotes  when  declared  in  the   "op" 
  1373.         declaration.  It  is  not necessary or legal to do this when  the 
  1374.         functor is actually being used as an operator.  In version 1.6, a 
  1375.         declared  or built-in operator can be used either as an  operator 
  1376.         or as a functor. For example, 
  1377.  
  1378.                                  +(2,3) = 2 + 3.
  1379.  
  1380.         is a true statement.
  1381.  
  1382.              Declared  operators  are annotated in the directory  display 
  1383.         with their precedence and associativity.
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.  
  1416.  
  1417.  
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.         Output predicates
  1426.  
  1427.            display
  1428.            write
  1429.            print
  1430.            put
  1431.  
  1432.              These  functions  have  been  modified  to  accept  multiple 
  1433.         arguments in the form:
  1434.  
  1435.                        print( <arg1>, <arg2>, <arg3>,... )
  1436.  
  1437.         Thus, "put( a, b, c )" would result in the display of "abc".
  1438.              The  names  of  some  PROLOG atoms that may  occur  are  not 
  1439.         accepted  by  the  PROLOG scanner  unless  surrounded  by  single 
  1440.         quotes.  This only applies when such an atom is read in, not when 
  1441.         it is internally generated. Nevertheless, this presents us with a 
  1442.         problem:  We  would  like to be capable of writing  valid  PROLOG 
  1443.         terms to a file. In some cases, it is necessary to add the single 
  1444.         quotes.  In other cases,  such as human oriented output, they are 
  1445.         an irritant. The modified definitions of the following predicates 
  1446.         are an attempt at a solution:
  1447.  
  1448.              display
  1449.              Operator  precedence  is ignored,  all functors are  printed 
  1450.              prefix and single quotes are printed if needed or they  were 
  1451.              supplied if and when the atom was originally input.
  1452.  
  1453.              write
  1454.              Operator  precedence is taken into account and operators are 
  1455.              printed according to precedence.  Single quotes are  printed 
  1456.              under the same conditions as for "display."
  1457.  
  1458.              print
  1459.              Operator  precedence is taken into account and operators are 
  1460.              printed  according to precedence.  Single quotes  are  never 
  1461.              displayed.  This  is  a  human oriented form of  output  and 
  1462.              should  never  be used for writing of terms for  the  PROLOG 
  1463.              scanner.
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.         get0
  1492.         read
  1493.  
  1494.              The  functions  "get0"  and "read"  have  been  extended  to 
  1495.         support input from a stream other than the one currently selected 
  1496.         by "see". To direct output to a file or other stream, an optional 
  1497.         argument  is used.  For example,  "get0( char,  <file name> )" or 
  1498.         "get0( char,  user )" would cause input to come from <file  name> 
  1499.         or the console.  If the file has not already been opened,  "get0" 
  1500.         will fail.
  1501.  
  1502.  
  1503.  
  1504.              Atoms enclosed by single quotest, eg. '\nthis is a new line' 
  1505.         can contain the escape sequences
  1506.  
  1507.              '\n', '\r', '\t' and '\''.
  1508.  
  1509.              If these atoms are printed by "display" or "write" they  are 
  1510.         printed  just  as they are.  If they are printed by  the  "print" 
  1511.         clause they are translated as follows:
  1512.  
  1513.         '\n'  results  in  the printing of a carriage return and  a  line 
  1514.         feed.
  1515.         '\r' results in the printing of a carriage return only.
  1516.         '\t' results in the printing of a tab character.
  1517.         '\'' allows the printing of a single quote within a quoted atom.
  1518.  
  1519.              The "portray" feature is not presently implemented.
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.                         Description of the New Predicates
  1558.  
  1559.  
  1560.         clearops-
  1561.  
  1562.              Nullify  the  operator  status  of  every  operator  in  the 
  1563.              database.
  1564.  
  1565.         concat( (<variable> | <functor>), <List> )
  1566.  
  1567.              A  list  of functors or operators is concatenated  into  one 
  1568.         string,  which becomes the name of a new atom to which <variable> 
  1569.         or <functor> must match or be instantiated.
  1570.  
  1571.  
  1572.         dir( option )
  1573.  
  1574.              Provide  an  alphabetized listing to the console  of  atoms, 
  1575.         constants,   or   open  files.   Without  options,   simply  type 
  1576.         "dir.<CR>". Options are:
  1577.  
  1578.              dir( p ) - list clause names only.
  1579.              dir( c ) - list consulted files only.
  1580.  
  1581.         Consulted files are prefixed by "S:".
  1582.  
  1583.  
  1584.         exitsys
  1585.  
  1586.              Exit to the operating system.
  1587.  
  1588.  
  1589.  
  1590.         forget( <file name> )
  1591.              Make  a database unavailable for use and reclaim the storage 
  1592.         it occupied.
  1593.  
  1594.  
  1595.  
  1596.         ratom( <arg>, <stream> )-
  1597.              Read an atom from the input stream,  to which <arg>  matches 
  1598.         or  is  instantiated.  <stream> is optional.  If <stream> is  not 
  1599.         given, the input stream defaults to the standar input.
  1600.              Input is terminated by a CR or LF, which are not included in 
  1601.         the stream.
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.                              Arithmetic Capabilities
  1624.  
  1625.              Integer  arithmetic is supported.  Numbers are 32 bit signed 
  1626.         quantities. The following arithmetic operators are supported:
  1627.  
  1628.                       "+", "-", "*", "/", <, <=, >, >=, mod.
  1629.  
  1630.         Arithmetic operators must never be used as goals,  although  they 
  1631.         may be part of structures. It is legal to write:
  1632.  
  1633.                                     X = a + b
  1634.              
  1635.         which  results in the instantiation of X to the struture (a + b). 
  1636.         But the following is not legal:
  1637.  
  1638.                        alpha( X, Y ) :- X + Y, beta( Y ).
  1639.  
  1640.  
  1641.         Evaluation  of  an arithemtic expression is mediated by the  "is" 
  1642.         and inequality predicates.  For instance,  the following would be 
  1643.         correct:
  1644.  
  1645.                          alpha( X, Y, Z ) :- Z is X + Y.
  1646.  
  1647.                          beta( X, Y ) :- X + 2 < Y + 3.
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.                             Memory Metric Predicate
  1690.  
  1691.              The purpose of this predicate is to give the prolog system 
  1692.         a  sense  of  how much memory remains so  that  expensive  search 
  1693.         strategies  can  be  controlled.  It is not possible  to  exactly 
  1694.         quantify how much memory remains.  At the lowest level, there are 
  1695.         two  types of memory - the stack and the heap.  The stack expands 
  1696.         down  from  high  memory,  while  the heap  tends  to  expand  at 
  1697.         unpredictable intervals upwards.  If the stack and heap meet, the 
  1698.         prolog  system  must abort the search and return to  the  prompt. 
  1699.         Judicious  use  of  the  memory  metric  predicates  reduces  the 
  1700.         probability of this happening.
  1701.  
  1702.              The  stack is easy to quantify because it expands  downwards 
  1703.         in  a  predictable  way with recursion.  The symbol  space  is  a 
  1704.         "heap".  For  those  interested,  the structure of  the  heap  is 
  1705.         determined  by  the C compiler under which Prolog  was  compiled. 
  1706.         There  is  a function internal to Prolog known as  the  allocator 
  1707.         searches  the  heap for enough contiguous memory to create a  new 
  1708.         symbol.  The  heap resembles a piece of Swiss cheese;  the  holes 
  1709.         represent symbols and already allocated memory while the remained 
  1710.         is  searched  by the allocator for a piece of  contiguous  memory 
  1711.         large enough to satisfy a request.  If one cannot be  found,  the 
  1712.         uppermost  bound of the heap is expanded upwards,  and that bound 
  1713.         is  the  number  which we measure for an  estimate  of  remaining 
  1714.         memory.
  1715.  
  1716.              The  sqace between the top of the heap,  and  the top of the 
  1717.         stack,  which we call "gap",  serves as a rough guide to how much 
  1718.         memory  remains.  The  demands  of the system  are  not  entirely 
  1719.         predictable,  however.  For example, the creation of a new symbol 
  1720.         larger  than "gap" would cause an abort.  The user must  use  the 
  1721.         numbers  supplied  by  these  functions  as  a  heuristic  guide, 
  1722.         tempered  by  experience,  to  minimize  the  possibility  of  an 
  1723.         unexpected abort.
  1724.  
  1725.         "Gap" is measured in 256 byte pages.
  1726.  
  1727.         memleft( X )
  1728.  
  1729.         If  the argument is an integer,  this is satisfied if the size of 
  1730.         "gap" is greater than "X".
  1731.  
  1732.         If the argument is a variable,  it is instantiated to the  amount 
  1733.         of "gap" remaining.
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.                          IBM PC Video Display Predicates
  1756.  
  1757.  
  1758.         A high level method is provided for drawing and displaying on the 
  1759.         screen of IBM PC and compatible computers. 
  1760.  
  1761.  
  1762.  
  1763.         cls
  1764.  
  1765.         Clear  the screen and position the cursor at the upper left  hand 
  1766.         corner.
  1767.  
  1768.  
  1769.  
  1770.         crtgmode( X )
  1771.  
  1772.         Matches  the  argument to the mode byte of the display  which  is 
  1773.         defined as follows:
  1774.  
  1775.                   mode           meaning
  1776.  
  1777.                    0             40 x  25  BW (default)
  1778.                    1             40 x  25  COLOR
  1779.                    2             80 x  25  BW
  1780.                    3             80 x  25  COLOR
  1781.                    4            320 x 200  COLOR
  1782.                    5            320 x 200  BW
  1783.                    6            640 x 200  BW
  1784.                    7             80 x  25  monochrome  display card
  1785.  
  1786.  
  1787.  
  1788.         crtset( X )
  1789.          
  1790.         This  sets the mode of the display.  The argument must be one  of 
  1791.         the modes given above. 
  1792.  
  1793.  
  1794.  
  1795.         curset( <row>, <column>, <page> )
  1796.  
  1797.         Sets the cursor to the given row, column, and page. The arguments 
  1798.         must be integers.
  1799.  
  1800.  
  1801.  
  1802.         curwh(  <row>, <column> )
  1803.  
  1804.         Reports the current position of the cursor.  The argument must be 
  1805.         an integer or variable. The format is:
  1806.  
  1807.              1) page zero is assumed.
  1808.              2) The row is in the range 0 to 79, left to right.
  1809.              3) The column is in the range 0 to 24, bottom to top.
  1810.         dotcolor( <row>, <column>, <color> )
  1811.  
  1812.         The  argument  <color> is matched to the color of  the  specified 
  1813.         dot. The monitor must be in graphics mode.
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.         drawchar( <character>, <attribute> )
  1824.  
  1825.         Put a character at the current cursor position with the specified 
  1826.         attribute.  The  arguments  <character> and <attribute>  must  be 
  1827.         integers.  Consult  the IBM technical reference manual  regarding 
  1828.         attributes.
  1829.  
  1830.  
  1831.  
  1832.         drawdot( <row>, <column>, <color> )
  1833.  
  1834.         Put  a dot at the specified position.  The monitor must be in the 
  1835.         graphics  mode.  The  arguments  must be  integer.  The  argument 
  1836.         <color> is mapped to integers by default in the following manner:
  1837.  
  1838.  
  1839.  
  1840.         drawline( <X1>, <Y1>, <X2>, <Y2>, <color> )
  1841.  
  1842.         Draw a line on the between the coordinate pairs. The monitor must 
  1843.         be in the graphics mode and the arguments are integer.
  1844.  
  1845.  
  1846.  
  1847.         prtscr
  1848.  
  1849.         Print  the  screen  as it currently appears.  Be  sure  that  the 
  1850.         printer  is  on  line and ready before invoking  this  predicate, 
  1851.         since otherwise, the system may lock up or abort.
  1852.  
  1853.  
  1854.  
  1855.         The  integer argument <color> referred to in the above predicates 
  1856.         is represented as follows:
  1857.  
  1858.              COLOR          PALETTE 0           PALETTE 1
  1859.              
  1860.                0            background          background
  1861.                1            green               cyan
  1862.                2            red                 magenta
  1863.                3            brown               white
  1864.  
  1865.         To change the palette and the background,  see the IBM  Technical 
  1866.         Reference Bios listings for more information.
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.  
  1875.  
  1876.  
  1877.  
  1878.  
  1879.  
  1880.  
  1881.  
  1882.  
  1883.  
  1884.  
  1885.  
  1886.  
  1887.                                    Trace Files
  1888.  
  1889.                                  (type ED only)
  1890.  
  1891.              You  can  now dump your trace to disk,  instead  of  (groan) 
  1892.         wasting  reams of printer paper.  This option is described in the 
  1893.         next section.
  1894.  
  1895.  
  1896.                                The Interrupt Menu
  1897.  
  1898.                                  (type ED only)
  1899.  
  1900.              This  menu  has been modified.  It was formerly  called  the 
  1901.         ESCAPE   menu,  but  the  meaning  of the  ESCAPE  key  has  been 
  1902.         redefined.  It  is  no  longer necessary to display the  menu  to 
  1903.         perform  one of the menu functions.  This reduces the  amount  of 
  1904.         display which is lost by scrolling off the screen.
  1905.  
  1906.              At any time while searching, printing, or accepting keyboard 
  1907.         input,  you can break to this menu.  It is generally not possible 
  1908.         to  do  this  during disk access,  since control  passes  to  the 
  1909.         operating  system  at this time.  Two keys cause  this  break  to 
  1910.         occur:
  1911.  
  1912.              ^V:  The menu is displayed and a command is accepted at the 
  1913.                   prompt  "INTERRUPT>".  After  a command,  the  menu  is 
  1914.                   redisplayed  until  the user selects  a  command  which 
  1915.                   causes an exit. 
  1916.  
  1917.              ^I:  The menu is not displayed.  Command is accepted at the 
  1918.                   prompt  "INTERRUPT>" until the user selects  a  command 
  1919.                   which causes an exit.
  1920.  
  1921.              ESC: Typing this key  causes a  termination of  the  PROLOG      
  1922.                   search  and  control returns to the user command  level      
  1923.                   with a prompt of "?-".  Notice that previously, the ESC      
  1924.                   key invoked this menu. 
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.              As the resulting menu indicates, the following functions are 
  1954.         possible:
  1955.  
  1956.              A: Abort the search and return to the prompt.
  1957.  
  1958.              O  Open  a trace file.  The user is prompted for  the  file 
  1959.                 name.  The file receives all trace output.  If a file is 
  1960.                 already opened it is closed with all output preserved.
  1961.  
  1962.              C  Close the trace file if one is open.  Otherwise there is 
  1963.                 no effect.
  1964.  
  1965.             ^C: Immediately  exit PROLOG without closing files.  This is 
  1966.                 not advised.
  1967.  
  1968.             ^P: Typing <Control>P toggles the printer. If the printer is 
  1969.                 on,  all  input  and output will also be  routed  to  the 
  1970.                 printer.
  1971.  
  1972.              S: If  the machine in use is an IBM PC compatible  machine, 
  1973.                 the  currently displayed screen will be printed.  If  the 
  1974.                 machine  is  not an IBM PC compatible,  do not  use  this 
  1975.                 function.
  1976.  
  1977.              T: If  trace  is in use,  most of the trace output  can  be 
  1978.                 temporarily turned off by use of this function,  which is 
  1979.                 a toggle.
  1980.  
  1981.              R:  Entering  another  ESC causes a return to the  current 
  1982.                 activity  (keyboard  input or search)  with  no  residual 
  1983.                 effect from the interruption.
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.  
  2003.  
  2004.  
  2005.  
  2006.  
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.                              Conserving memory space
  2021.  
  2022.  
  2023.                Success popping is controlled by the predicates "popond",
  2024.         "popoffd",  "popon",  and  "popoff".  Success popping is means of 
  2025.         reclaiming  storage which is used on backtracking to  reconstruct 
  2026.         how a particular goal was satisfied.  If it is obvious that there 
  2027.         is no alternative solution to a goal this PROLOG system is  smart 
  2028.         enough to reclaim that storage. 
  2029.  
  2030.              In  this system,  succees popping is an expensive operation. 
  2031.         Therefore,  there  is a tradeoff of memory versus  time.  On  the 
  2032.         other hand, discrete use of success popping can actually speed up 
  2033.         a program by recreating structures in a more accessible form.
  2034.  
  2035.              The  definitions of the control predicates is given in  this 
  2036.         manual  and  their use is totally  optional.  The  modulation  of 
  2037.         success popping has no effect on program logic (read solution.)
  2038.              
  2039.              The  "cut"  can  save  substantial  time  and  computational 
  2040.         overhead  as well as storage.  Although the execution of the  cut 
  2041.         costs  time,  you can design your program to use cuts in critical 
  2042.         places  to  avoid unnecessary backtracking.  Thus  the  execution 
  2043.         speed of the program can actually increase. 
  2044.              
  2045.              Anyone  who  has  read Clocksin and  Mellish  is  aware,  of 
  2046.         course, that the "cut" has a powerful logical impact which is not 
  2047.         always desirable.
  2048.  
  2049.  
  2050.         popoff 
  2051.  
  2052.         See the below definition.
  2053.  
  2054.  
  2055.  
  2056.         popon
  2057.  
  2058.         The  inference  engine  does complete success popping  for  goals 
  2059.         which appear after "popon".  Consider this example: 
  2060.  
  2061.           goal :-  a, popon, b, c, popoff, d.
  2062.  
  2063.         If  no alternative solutions exist for b,  then  success  popping 
  2064.         will  reclaim storage by removing unnecessary records  describing 
  2065.         how  "b"  was  satisfied.  If the Prolog system cannot  rule  out 
  2066.         possible additional solutions,  success popping will never occur, 
  2067.         regardless of your use of "popon". 
  2068.              Since goal "d" occurs after "popoff",  success popping  will 
  2069.         never occur.
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.         popoffd
  2086.  
  2087.         If  no  "popon" or "popoff" declarations occur in a  clause,  the 
  2088.         default  action  is  determined by  "popoffd"  and  "popond".  If 
  2089.         "popoffd" has been invoked,  the default is that success  popping 
  2090.         will not occur.
  2091.  
  2092.  
  2093.  
  2094.         popond
  2095.  
  2096.         The inverse of "popoffd". Turns on default success popping.
  2097.         printf( <stream>, <term1>,<term2>,... )
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.  
  2124.  
  2125.  
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.  
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139.  
  2140.  
  2141.  
  2142.  
  2143.  
  2144.  
  2145.  
  2146.  
  2147.  
  2148.  
  2149.  
  2150.  
  2151.                                  Prolog Tutorial          
  2152.  
  2153.  
  2154.                                   Introduction
  2155.  
  2156.  
  2157.  
  2158.  
  2159.              Probably  you  have heard of the language PROLOG within  the 
  2160.         last year or so. You probably wondered the following things:
  2161.  
  2162.         1) What does the name stand for? Names of computer languages are 
  2163.         almost always acronyms.
  2164.  
  2165.         2) What is it good for?
  2166.  
  2167.         3) Why now?
  2168.  
  2169.         4) Can I get a copy to play with?
  2170.  
  2171.              Congratulations! You obviously know the answer to the fourth 
  2172.         question. We now respond to the other three.
  2173.              
  2174.         1)  The  name  stands for "programming in logic." This  we  shall 
  2175.         elaborate on in depth later on.
  2176.  
  2177.         2) PROLOG is good for writing question answering systems.  It  is 
  2178.         also   good   for  writing  programs  that  perform   complicated 
  2179.         strategies  that  compute the best or worst way to  accomplish  a 
  2180.         task, or avoid an undesirable result.
  2181.  
  2182.         3) PROLOG was virtually unknown in this country until researchers 
  2183.         in  Japan announced that it was to be the core language  of  that 
  2184.         country's fifth generation computer project.  This is the project 
  2185.         with  which  Japan hopes to achieve a domainant position  in  the 
  2186.         world information industry of the 1990's. 
  2187.  
  2188.              PROLOG  is  one of the most unusual computer languages  ever 
  2189.         invented.  It  cannot be compared to  FORTRAN,  PASCAL,  "C",  or 
  2190.         BASIC.  The facilities complement,  rather than replace those  of 
  2191.         conventional  languages.  Although  it  has great  potential  for 
  2192.         database  work,  it  has  nothing in  common  with  the  database 
  2193.         languages used on microcomputers.
  2194.  
  2195.              Perhaps  the  best point to make is that while  conventional 
  2196.         languages are prescriptive, PROLOG is descriptive. A statement in 
  2197.         a conventional language might read:
  2198.  
  2199.              if( car_wheels = TRUE ) then
  2200.                begin
  2201.                  (some sort of procedure)
  2202.                  X = X + 1;
  2203.                end 
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.         A statment in PROLOG could just be a statment of fact about  cars 
  2218.         and wheels. There are many relationships that hold. For instance,
  2219.  
  2220.              has( car, wheels ).
  2221.  
  2222.              has( car, quant(wheels, four) ).
  2223.  
  2224.              round( wheels ).
  2225.  
  2226.         Each  of  these statments is an independent fact  relating  cars, 
  2227.         wheels,  and  the  characteristics of wheels.  Because  they  are 
  2228.         independent, they can be put into a PROLOG program by programmers 
  2229.         working separately. The man who is a specialist on car bodies can 
  2230.         say  his thing,  the wheel specialist can have his say,  and  the 
  2231.         participants can work with relative independence. And this brings 
  2232.         to light a major advantage of PROLOG:
  2233.  
  2234.  
  2235.                              PARALLEL PROGRAMMING!!!
  2236.                             
  2237.  
  2238.         With  conventional  programming languages projects can  still  be 
  2239.         "chunked",  or  divided between programmers.  But efficiency on a 
  2240.         team  project  drops  drastically below that  of  the  individual 
  2241.         programmer  wrapped  up  in  his own trance.  As  the  number  of 
  2242.         participants    grows   the   need   for   communication    grows 
  2243.         geometrically. The time spent communicating can exceed that spent 
  2244.         programming! 
  2245.              Although   PROLOG   does   not  eliminate   the   need   for 
  2246.         task  coordination,  the problem is considerably  simplified.  It 
  2247.         also provides the ability to answer questions in a "ready to  eat 
  2248.         form."  Consider your favorite BASIC interpreter.  Based upon the 
  2249.         statements about cars and wheels previously given,  could you ask 
  2250.         it the following question?   
  2251.  
  2252.                        
  2253.               has( car, X ), round( X ).
  2254.  
  2255.              Does  a  car  have anything which  is  round?  The  question 
  2256.         instructs the PROLOG interpreter to consider all the objects that 
  2257.         it  knows are possessed by a car and find those which are  round. 
  2258.         Perhaps  you are beginning to guess that PROLOG has the abilities 
  2259.         of a smart database searcher.  It can not only find the facts but 
  2260.         selectively find them and interpret them.
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.              Consider the problem of a fault tree, as exemplified by this 
  2284.         abbreviated one:
  2285.  
  2286.  
  2287.  
  2288.         {Car won't start}
  2289.              | 
  2290.              | 
  2291.         [Engine  turns  over](No) --> [Battery voltage](no)-\
  2292.                 (Yes)                                       v
  2293.                  |                                  {Check battery}
  2294.                  |
  2295.         [Smell gasoline](yes) --> {Try full throttle cranking}
  2296.                  |                       (failure)
  2297.         /--------/                           |
  2298.  
  2299.                             (details omitted)
  2300.  
  2301.  
  2302.  
  2303.              The fault tree is easily programmed in BASIC. Later we shall 
  2304.         show  that  PROLOG supplies a superior replacement for the  fault 
  2305.         tree.  Though the tree is capable of diagnosing only the  problem 
  2306.         for  which  it was designed,  PROLOG dynamically  constructs  the 
  2307.         appropriate  tree from facts and rules you have provided.  PROLOG 
  2308.         is not limited to answering one specific question.  Given  enough 
  2309.         information,  it  will attempt to find all deductive solutions to 
  2310.         any problem.
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.  
  2318.  
  2319.  
  2320.  
  2321.  
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.                                   PROLOG PRIMER
  2351.  
  2352.         I.                       Rules and Facts     
  2353.  
  2354.  
  2355.  
  2356.              This  is  where you should start if you know  nothing  about 
  2357.         PROLOG. Let us consider a simple statment in PROLOG, such as:
  2358.  
  2359.         1)   has( car, wheels ).
  2360.  
  2361.         This  statement  is a "fact.  The word "has" in this statment  is 
  2362.         known  either  as a functor or predicate.  It is a name  for  the 
  2363.         relationship  within the parenthesis.  It implies that a car  has 
  2364.         wheels.  But  the  order  of  the words  inside  the  bracket  is 
  2365.         arbitrary and established by you. You could just as easily say:
  2366.  
  2367.         2)   has( wheels, car ).
  2368.  
  2369.         and if you wrote this way consistently,  all would be  well.  The 
  2370.         words  has,  wheels,  and car are all PROLOG atoms.  "Wheels" and 
  2371.         "car" are constants. 
  2372.              
  2373.         A   database   of  facts  can  illustrate  the   data   retrieval 
  2374.         capabilities of PROLOG. For instance:
  2375.  
  2376.         3)   has( car, wheels ).
  2377.              has( car, frame ).
  2378.              has( car, windshield ).
  2379.              has( car, engine ).
  2380.  
  2381.         You could then ask PROLOG the question:
  2382.  
  2383.         4)   has( car, Part ).
  2384.  
  2385.         The  capital  "P" of Part means that Part is a  variable.  PROLOG 
  2386.         will make Part equal to whatever constant is required to make the 
  2387.         question match one of the facts in the database. Thus PROLOG will 
  2388.         respond:
  2389.  
  2390.              Part = wheels.
  2391.              
  2392.              More?(Y/N):
  2393.  
  2394.         If you type "y" the next answer will appear:
  2395.  
  2396.              Part = frame.
  2397.  
  2398.              More?(Y/N):
  2399.  
  2400.         If you continue, PROLOG will produce the answers Part = windshield 
  2401.         and Part = engine. Finally, you will see:
  2402.  
  2403.              More?(Y/N):y
  2404.  
  2405.              No.
  2406.          
  2407.         indicating that PROLOG has exhausted the database.  Incidentally, 
  2408.         when  a  variable is set equal to a constant or  other  variable, 
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.         it is said to be instantiated to that object.
  2416.  
  2417.              Notice  that  PROLOG searches the database forwards  and  in 
  2418.         this case,  from the beginning.  The forward search path is built 
  2419.         into PROLOG and cannot be changed. An author of a program written 
  2420.         in  a  prescriptive language is quite conscious of the  order  of 
  2421.         execution  of  his program,  while in PROLOG it is  not  directly 
  2422.         under his control.
  2423.              
  2424.              The other major element is the rule which is a fact which is 
  2425.         conditionally true. In logic this is called a Horn clause: 
  2426.  
  2427.  
  2428.         5)   has( X, wheels ) :- iscar( X ).
  2429.  
  2430.         The  fact iscar( car ) and the above rule are equivalent to
  2431.  
  2432.         6)   has( car, wheels).
  2433.  
  2434.         The  symbol :- is the "rule sign." The expression on the left  of 
  2435.         :-is the "head" and on the right is the body.  The variable X has 
  2436.         scope  of the rule,  which means that it has meaning only  within 
  2437.         the rule.  For instance,  we could have two rules in the database 
  2438.         using identically named variables.
  2439.  
  2440.  
  2441.         7)   has( X,  transportation ) :- 
  2442.                            has( X,  car ), has( license, X ).
  2443.  
  2444.         8)   has( X, elephant ) :- istrainer( X ), hasjob( X ).
  2445.  
  2446.         The  variables  X in the two expressions are completely  distinct 
  2447.         and have nothing to do with each other.
  2448.  
  2449.         The comma between has( X, car ) and has( license, X ) means "and" 
  2450.         or logical conjuction.  The rule will not be true unless both the 
  2451.         clauses has(X, car) and has( license, X ) are true.
  2452.  
  2453.  
  2454.              On the other hand if there is a rule
  2455.              
  2456.         9)   has( license, X ) :- passedexam( X ).
  2457.  
  2458.         consider what PROLOG will do in response to the question:
  2459.  
  2460.         10)  has( harry, transportation ).
  2461.  
  2462.         (Notice  that  harry has not been capitalized because we  do  not 
  2463.         want  it  taken as a variable.  We could,  however,  say  'Harry' 
  2464.         enclosed in single quotes.)
  2465.  
  2466.              It  will scan the database and use (7),  in which X will  be 
  2467.         instantiated to harry. The rule generates two new questions:
  2468.  
  2469.         11)  has( harry, car ).
  2470.  
  2471.         12)  has( license, harry ).
  2472.  
  2473.         Assuming  that  harry  has  a car,  the first clause  of  (7)  is 
  2474.         satisfied and the database is scanned for a match to (12). PROLOG 
  2475.  
  2476.  
  2477.  
  2478.  
  2479.  
  2480.  
  2481.         picks  up  rule (9) in which X is instantiated to harry  and  the 
  2482.         question is now posed:
  2483.  
  2484.         13)  passedexam( harry ).
  2485.  
  2486.              If there is a fact:
  2487.  
  2488.              passedexam( harry ).
  2489.  
  2490.         in  the database then all is well and harry  has  transportation. 
  2491.         If there is not, then PROLOG will succinctly tell you:
  2492.  
  2493.              No.
  2494.  
  2495.         But  suppose Harry has money and can hire a chauffer as any  good 
  2496.         programmer  can.  That  could be made part of the program in  the 
  2497.         following way.
  2498.  
  2499.              The rule which PROLOG tried to use was:
  2500.  
  2501.         14)  has( X,  transportation ) :- 
  2502.                            has( X,  car ), has( license, X ).
  2503.  
  2504.         At any point following it there could be included another rule:
  2505.  
  2506.         15)  has( X, transportation ) :- has( X, money ).
  2507.  
  2508.         or simply the bald fact:
  2509.  
  2510.         16)  has( harry, transportation ).
  2511.  
  2512.              These  additional  rules  or  facts would  be  used  in  two 
  2513.         circumstances.  If at any point a rule does not yield a solution, 
  2514.         PROLOG   will  scan  forward  from  that  rule  to  find  another 
  2515.         applicable  one.  This process is known as "backtracking  search" 
  2516.         and can be quite time consuming.
  2517.  
  2518.  
  2519.         If  in response to the "More?" prompt you answer "y" PROLOG  will 
  2520.         search  for an additional distinct solution.  It will attempt  to 
  2521.         find an alternate rule or fact for the last rule or fact used. If 
  2522.         that  fails,  it  will back up to the antecedent rule and try  to 
  2523.         find  an alternate antecedent.  And it will continue to  back  up 
  2524.         until  it  arrives at the question you asked,  at which point  it 
  2525.         will say:
  2526.  
  2527.              No.
  2528.  
  2529.         "Antecedent"  to a rule means that it gave rise to its' use.  For 
  2530.         example,  (7)  is  the antecedent of (9) in the  context  of  the 
  2531.         question (16).
  2532.  
  2533.  
  2534.  
  2535.  
  2536.         II.                          Grammar
  2537.  
  2538.              It is a boring subject, but it must be discussed. All PROLOG 
  2539.         statements are composed of valid terms, possibly a rule sign (":-
  2540.         "),  commas representing conjunction ("and"), and a period at the 
  2541.  
  2542.  
  2543.  
  2544.  
  2545.  
  2546.  
  2547.         very end.
  2548.              A term is a structure, constant, variable, or number.
  2549.          
  2550.              What is a structure? It is a kind of grouping:
  2551.  
  2552.              1) Structures consist of a functor, and a set of objects or
  2553.                 structures in parenthesis.
  2554.  
  2555.              2)  Objects are constants,  variables,  numbers,  or  lists, 
  2556.                 which we have not discussed yet.
  2557.  
  2558.              3)  A  constant or functor must be a string of  letters  and 
  2559.                 numbers, beginning with a lower case letter, unless
  2560.                 you  choose  to  enclose  it in single  quotes  (  'howdy 
  2561.                 pardner'  ),  in  which  case you are  freed  from  these 
  2562.                 restrictions.
  2563.              4) A  variable  must be a string of  letters  and  numbers 
  2564.                 beginning with a capital letter.
  2565.              
  2566.              5) A  functor  may optionally have  arguments  enclosed  in 
  2567.                 parenthesis , as in: hascar( X ) or hascar. 
  2568.  
  2569.         An example:  "has( X, transportation )." is a structure.
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.         III.                     Input / Output      
  2614.  
  2615.              You   now   know  enough  to  write  simple  databases   and 
  2616.         interrogate   them  profitably.   But  before  we  examine   more 
  2617.         sophisticated  examples,  it  will be necessary to add input  and 
  2618.         output to the language. There are built in functions which appear 
  2619.         as rules which are satisfied once. Thus the statment:
  2620.  
  2621.              write( 'Hello world.' ).
  2622.  
  2623.         can be included on the right side of a rule:
  2624.  
  2625.  
  2626.         greetings(  X ) :- ishuman( X ),  write( 'Hello world.' ).  You 
  2627.         can  also write "write( X )" where X is some variable.  Note that 
  2628.         'Hello  world.' is not enclosed in double quotes.  Single quotes, 
  2629.         which denote a constant, are required. Double quotes would denote 
  2630.         a list, which is another thing entirely.
  2631.  
  2632.         Provided  that  a match to "ishuman" can be  found,  the  builtin 
  2633.         function  "write"  is  executed and the message  printed  to  the 
  2634.         screen.
  2635.              The  builtin  read( X ) reads a "structure" that  you  input 
  2636.         from the keyboard. More formally, we have
  2637.  
  2638.              read( <variable> or <constant> )
  2639.              write( <variable> or <constant> )
  2640.  
  2641.         If you write read( Input ),  then the variable "keyboard" will be 
  2642.         assigned to whatever is typed at the keyboard,  provided that the 
  2643.         input  is a valid PROLOG structure.  The builtin "read" will fail 
  2644.         if instead of Keyboard we wrote read( baloney ),  where "baloney" 
  2645.         is a constant,  and the user at the keyboard did not type exactly 
  2646.         "baloney." 
  2647.  
  2648.         When you input a structure in response to a "read" statement,  be 
  2649.         sure to end it with a period and an <ENTER>. 
  2650.  
  2651.              There  is  a convenient way of putting the cursor on  a  new 
  2652.         line. This is the builtin "nl". For example:
  2653.  
  2654.              showme :- write( 'line 1' ), nl, write( 'line 2' ). 
  2655.  
  2656.         would result in:
  2657.  
  2658.              line 1
  2659.              line 2
  2660.  
  2661.              There  is  also a primitive form of input/output for  single 
  2662.         characters. It will be discussed later.
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.  
  2676.  
  2677.  
  2678.  
  2679.         IV.                   A Fault Tree Example
  2680.  
  2681.              Consider the "won't start" fault tree for an automobile:
  2682.  
  2683.         {Car won't start}
  2684.              | 
  2685.              | 
  2686.         [Engine  turns  over](No) --> [Battery voltage](no)-\
  2687.                 (Yes)                                       v
  2688.                  |                                  {Check battery}
  2689.                  |
  2690.         [Smell gasoline](yes) --> {Try full throttle cranking}
  2691.                  |                       (failure)
  2692.         /--------/                           |
  2693.         |           /------------------------/ 
  2694.         |           |                       
  2695.         |           |
  2696.         |  [Check for fuel line leaks](yes)-->{Replace fuel line}
  2697.         |          (no)
  2698.         |           |
  2699.         |           |
  2700.         |  [Check for defective carburator](yes)--\
  2701.         |          (no)                           v
  2702.         |                                {Repair carburator}
  2703.         \----\
  2704.              |
  2705.              |
  2706.         [Is spark present](no)-->[Do points open and close](no)-\
  2707.              |                             (yes)                v
  2708.         /----/                               |          {Adjust points}
  2709.         |           /------------------------/
  2710.         |           |
  2711.         |  [Pull distributor wire, observe spark](blue)--\
  2712.         |        (orange)                                v
  2713.         |           |                           {Check plug wires & cap}
  2714.         |           |
  2715.         |  [Measure voltage on coil primary](not 12V)--\
  2716.         |         (12V)                                v
  2717.         |           |              {Check wiring, ballast resistor}
  2718.         |           |
  2719.         |  [Check condenser with ohmmeter](conducts)--\
  2720.         |    (no conduction)                          v
  2721.         |           |                         {Replace condenser}
  2722.         |           |
  2723.         |  [Open and close points](voltage not 0 - 12)--\
  2724.         |   (voltage swings 0 - 12)                     v
  2725.         |           |                         {Fix primary circuit}
  2726.         |           |
  2727.         |  {Consider hidden fault, swap components]
  2728.         |
  2729.         |
  2730.         \-------{Call a tow truck!!}
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736.  
  2737.  
  2738.  
  2739.  
  2740.  
  2741.  
  2742.  
  2743.  
  2744.  
  2745.              A PROLOG program to  implement this is simple. Each statment 
  2746.         represents  a  decision point fragment of the  tree.  The  PROLOG 
  2747.         interpreter  dynamically  assembles  the tree as  it  attempts  a 
  2748.         solution. 
  2749.  
  2750.         'car wont start' :- write( 'Is the battery voltage low?' ), 
  2751.                             affirm, nl,
  2752.                             write( 'Check battery' ).
  2753.  
  2754.         'car wont start' :- write( 'Smell gasoline?' ), 
  2755.                             affirm, nl,
  2756.                             'fuel system'.
  2757.  
  2758.         'fuel system'    :- write( 'Try full throttle cranking' ).
  2759.  
  2760.         'fuel system'    :- write( 'Are there fuel line leaks?' ),
  2761.                             affirm, nl,
  2762.                             write( 'Replace fuel line.' ).
  2763.  
  2764.         'fuel system'    :- write( 'Check carburator' ).
  2765.  
  2766.         'car wont start' :- write( 'Is spark present?' ),
  2767.                             not( affirm ), nl,
  2768.                             'no spark'.
  2769.  
  2770.         'no spark'       :- write( 'Do points open and close?' ),
  2771.                             not( affirm ), nl,
  2772.                             write( 'Adjust or replace points.' ).
  2773.  
  2774.         'no spark'       :- write( 'Is the spark off the coil good?' ),
  2775.                             affirm,
  2776.                             write( 'Check plug wires and cap.' ).
  2777.  
  2778.         'no spark'       :- write( 'What is the voltage on the primary
  2779.                              of the coil: ' ), 
  2780.                             read( Volts ), 
  2781.                             Volts < 10,
  2782.                             nl,
  2783.                             write('Check wiring and ballast resistor.').
  2784.  
  2785.         'no spark'       :- write( 'Does the capacitor leak?' ),
  2786.                             affirm,
  2787.                             write( 'Replace the capacitor.' ).
  2788.  
  2789.         'no spark'       :- not( 'primary circuit' ).
  2790.  
  2791.         'primary circuit' 
  2792.                          :- write( 'Open the  points.  Voltage  across 
  2793.                               coil?:'), nl,
  2794.                             read( Openvolts ), Openvolts < 1, 
  2795.                             write(  'Close the points.  Voltage  across 
  2796.                               coil?:'),
  2797.                             read( Closevolts ), Closevolts > 10, nl,
  2798.                             write( 'Primary circuit is OK.' ). 
  2799.  
  2800.         'no spark'       :- write( 'Consider a hidden fault. Swap
  2801.                               cap, rotor,points,capacitor.' ).
  2802.  
  2803.  
  2804.         'Car wont start' :- write( 'Get a tow truck!!' ).
  2805.  
  2806.  
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812.  
  2813.                                  --End program--
  2814.  
  2815.  
  2816.              The  above  is  a  simple example of  an  expert  system.  A 
  2817.         sophisticated  system would tell you exactly the method by  which 
  2818.         it  has reached a conclusion.  It would communicate by a  "shell" 
  2819.         program  written  in PROLOG which would accept a wider  range  of 
  2820.         input   than  the  "valid  structure"  required  by  the   PROLOG 
  2821.         interpreter directly.
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.  
  2840.  
  2841.  
  2842.  
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860.  
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.  
  2872.  
  2873.  
  2874.  
  2875.  
  2876.  
  2877.         V.                            Lists               
  2878.  
  2879.              Consider  a  shopping list given you by your wife.  It is  a 
  2880.         piece of paper with items written on it in an order that probably 
  2881.         symbolizes  their  importance.  At the top it  may  say  EGGS!!!, 
  2882.         followed by carrots, hamburger, and finally a flea collar for the 
  2883.         dog, if you can find one. In PROLOG such a list would be written:
  2884.  
  2885.         1)   [eggs, carrots, hamburger, fleacollar]
  2886.  
  2887.         The  order of a list is important so that eggs and carrots cannot 
  2888.         be reversed and PROLOG be uncaring.
  2889.  
  2890.         Let us put the list in a structure:
  2891.  
  2892.              shopping( [eggs, carrots, hamburger, fleacollar] ).
  2893.  
  2894.         Then  if you wished to isolate the head of the list you could ask 
  2895.         the question:
  2896.  
  2897.              shopping( [ Mostimportant | Rest ] ).
  2898.  
  2899.         and PROLOG would respond:
  2900.  
  2901.              Mostimportant   =  eggs,   
  2902.              Rest   =   [carrots,   hamburger, fleacollar].
  2903.  
  2904.         The vertical bar "|" is crucial here. It is the string extraction 
  2905.         operator,  which  performs  a  combination  of the  CDR  and  CAR 
  2906.         functions  of LISP.  When it appears in the context [X|Y] it  can 
  2907.         separate the head of the list from the rest, or tail.
  2908.  
  2909.  
  2910.              You  may have gained the impression that PROLOG is a  rather 
  2911.         static language capable of answering simple questions,  but it is 
  2912.         far  more powerful than that.  The string extraction operator  is 
  2913.         the  key.  It permits PROLOG to whittle a complex expression down 
  2914.         to the bare remainder.  If the rules you have given it permit  it 
  2915.         to  whittle  the  remainder  down to  nothing,  then  success  is 
  2916.         achieved. An example of this is the definition of "append."
  2917.  
  2918.              Let  us suppose you have not yet done yesterday's  shopping, 
  2919.         let alone today's. You pull it out of your wallet and sootch tape 
  2920.         it to the list your wife just gave you. Yesterday's list was:
  2921.  
  2922.              [tomatoes, onions, ketchup]
  2923.  
  2924.         Combined with [eggs, carrots, hamburger, fleacollar] we obtain
  2925.  
  2926.              [eggs,carrots,hamburger,fleacollar,tomatoes,onions,garlic].
  2927.  
  2928.         To  take one list and to attach it to the tail of another list is 
  2929.         to  "append"  the first to the second.  The PROLOG definition  of 
  2930.         append is:
  2931.  
  2932.  
  2933.  
  2934.         Rule1:     append( [], L, L ).
  2935.  
  2936.         Rule2:     append( [X|List1], List2, [X|List3] ) :-
  2937.  
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.                       append( List1, List2, List3 ].
  2944.  
  2945.         The  general  scheme is this:  
  2946.  
  2947.         The definition consists of one rule and one fact.  The rule  will 
  2948.         be used over and over again until what little is left matches the 
  2949.         fact.  The [] stands for empty list,  which is like a bag without 
  2950.         anything in it. This is an example of a recursive definition.
  2951.              Suppose we ask:
  2952.  
  2953.              append( [a,b,c], [d,e,f], Whatgives ).
  2954.  
  2955.         1. Rule 2 is invoked with arguments ( [a,b,c], [d,e,f], Whatgives ).
  2956.         2. Rule 2 is invoked again with arguments:
  2957.              ( [b,c], [d,e,f], List3 ).
  2958.         3. Rule 2 is invoked again with arguments:
  2959.              ( [b], [d,e,f], List3 ).
  2960.         4.  The  arguments  are now ([],  [d,e,f],  List3 ).  Rule 1  now 
  2961.             matches. End.
  2962.  
  2963.         How does this cause a list to be constructed? The key is to watch 
  2964.         the   third  argument.   Supplied  by  the  user,   it  is  named 
  2965.         "Whatgives". The inference engine matches it to [X|List3] in rule 
  2966.         2. Now lets trace this as rule two is successivly invoked: 
  2967.  
  2968.  
  2969.                 Whatgives                                                
  2970.                    |                                                     
  2971.                    |                                                     
  2972.                    |                                                     
  2973.                    v                                                     
  2974.         Rule2:  [X|List3] (List1 = [b,c])                                
  2975.                  |  \                                                    
  2976.                  |   \                                                   
  2977.                  |    \                                                  
  2978.                  v     \                                                 
  2979.         Rule2:   a   [X'|List3'] (List1' = [c])                          
  2980.                       |    \                                             
  2981.                       |     \                                            
  2982.                       |      \                                           
  2983.                       v       \                                          
  2984.         Rule2:        b     [X''|List3''] (List1'' = [], ie., empty set.)
  2985.                               |    \                                     
  2986.                               |     \                                    
  2987.                               |      \                                   
  2988.         Rule1:                c       L  ( in Rule1 = [d,e,f] )              
  2989.                                                                          
  2990.         End.
  2991.  
  2992.  
  2993.         L in rule 1 is [d,e,f] for the following reason: Notice that rule 
  2994.         2 never alters List2. It supplies it to whatever rule it invokes. 
  2995.         So L in rule 1 is the original List2, or [a,b,c].
  2996.  
  2997.              This example would not have worked if the order of rules one 
  2998.         and  two  were  reversed.  The  PROLOG  inference  engine  always 
  2999.         attempts to use the the first rule encountered. You could imagine 
  3000.         it as always reading your program from the top down in attempting 
  3001.         to  find an appropriate rule.  Since rule 2 would always satisfy, 
  3002.         an  unpleasant  thing  would  have happened  if  the  order  were 
  3003.  
  3004.  
  3005.  
  3006.  
  3007.  
  3008.  
  3009.         reversed. The program would loop forever.
  3010.              
  3011.  
  3012.  
  3013.  
  3014.              I  hope  that  this tiny introduction to PROLOG  whets  your 
  3015.         appetite. You should now purchase the book
  3016.  
  3017.              Programming In Prolog
  3018.              W.F. Clocksin and C.S. Mellish
  3019.              Springer - Verlag
  3020.              Berlin,Heidelberg,New York. 1981,1984
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037.  
  3038.  
  3039.  
  3040.  
  3041.  
  3042.  
  3043.  
  3044.  
  3045.  
  3046.  
  3047.  
  3048.  
  3049.  
  3050.  
  3051.  
  3052.  
  3053.  
  3054.  
  3055.  
  3056.  
  3057.  
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.  
  3073.  
  3074. read_in([W|Ws]) :- get0(C), readword(C,W,C1), restsent(W,C1,Ws).
  3075.  
  3076. restsent( W,_,[]) :- lastword(W), !.
  3077. restsent(W,C,[W1|Ws]) :- readword(C,W1,C1), restsent(W1,C1,Ws).
  3078.  
  3079. readword(C,W,C1) :- single_character(C), !, name(W,[C]), get0(C1).
  3080. readword(C,W,C2) :-
  3081.     in_word(C,NewC), !,
  3082.     get0(C1),
  3083.     restword(C1,Cs,C2),
  3084.     name(W,[NewC|Cs]).
  3085. readword(C,W,C2) :- get0(C1), readword(C1,W,C2).
  3086.  
  3087. restword(C,[NewC|Cs],C2) :-
  3088.     in_word(C,NewC), !,
  3089.     get0(C1),
  3090.     restword(C1,Cs,C2).
  3091. restword(C,[],C).
  3092.  
  3093. single_character(44).  /* , */
  3094. single_character(59).  /* ; */
  3095. single_character(58).  /* : */
  3096. single_character(63).  /* ? */
  3097. single_character(33).  /* ! */
  3098. single_character(46).  /* . */
  3099.  
  3100. in_word(C,C) :- C>96, C<123.                /* a b..z */
  3101. in_word(C,L) :- C>64, C<91, L is C+32.      /* A,B..Z */
  3102. in_word(C,C) :- C>47, C<58.                 /* 1,2,..9 */
  3103. in_word(39,39).                             /*  ' */
  3104. in_word(45,45).                             /* - */
  3105.  
  3106. lastword( '.' ).
  3107. lastword( '!' ).
  3108. lastword( '?' ).
  3109.  
  3110. answer(A) :- ratom( X ), conv( X, A ), !.
  3111.  
  3112. conv(X,I) :- atoi( X, I ), 0 < I, I < 4, !.
  3113. conv(X,A) :- name( X, String ), valid_resp( String, A ), !.
  3114.  
  3115.  
  3116. valid_resp( [H|T], A ) :- type_ans( H, A ).
  3117.  
  3118. type_ans( X, A ) :- ([X] = "h"; [X] = "H"), A = help.
  3119. type_ans( X, A ) :- ([X] = "w"; [X] = "W"), A = why.
  3120.  
  3121. valid_resp( [], A ) :-
  3122.     print('\nPlease try to give me a H,W, or number for an answer.'),
  3123.     answer( A ), !.
  3124.  
  3125. valid_resp( [H|T], A ) :- valid_resp( T, A ).
  3126.  
  3127.  
  3128.  
  3129. /* Makes new atoms, one at a time. Do not expect a repeat solution. 
  3130. You must ask each time you want an atom. It starts with some root,
  3131. and appends an incrementing number onto it. 
  3132.  
  3133. Ask: ?-gensym( student, X ).      get: X = student1.
  3134.      ?-gensym( student, X ).      get: X = student2.
  3135.      ?-gensym( student, X ).      get: X = student3.
  3136.  
  3137.     and ad infinitum. */
  3138.  
  3139. gensym( Root, Atom ) :-
  3140.     get_num( Root, Num ),
  3141.     name( Root, Name1 ),
  3142.     integer_name( Num, Name2 ),
  3143.     append( Name1, Name2, Name ),
  3144.     name( Atom, Name ).
  3145.  
  3146. get_num( Root, Num ) :-
  3147.     retract( current_num( Root, Num1 )), !,
  3148.     Num is Num1 + 1,
  3149.     asserta( current_num( Root, Num)).
  3150.  
  3151. get_num( Root, 1 ) :- asserta( current_num( Root, 1 )).
  3152.  
  3153. integer_name( Int, List ) :- integer_name( Int, [], List ).
  3154. integer_name( I, Sofar, [C|Sofar] ) :-
  3155.     I < 10, !, C is I + 48.
  3156. integer_name( I, Sofar, List ) :-
  3157.     Tophalf is I/10,
  3158.     Bothalf is I mod 10,
  3159.     C is Bothalf + 48,
  3160.     integer_name( Tophalf, [C|Sofar], List ).
  3161.  
  3162.  
  3163. append( [], L, L ).
  3164. append( [Z|L1], L2, [Z|L3] ) :- append( L1, L2, L3 ).
  3165.  
  3166. printstring( [] ).
  3167. printstring( [] ).
  3168. printstring( [H|T] ) :- put( H ), printstring( T ).
  3169.  
  3170. /*
  3171. .PN1
  3172. .PO0 */
  3173.  
  3174. signs :- nl, 
  3175.   print( 'Does the patient exhibit any of the following signs:' ), nl,
  3176.   print( 'weakness, lightheadedness, syncope, cardiac awareness,
  3177.   pallor, tachycardia, jaundice.' ), 
  3178.   affirm,
  3179.   syndrome( 1 ).
  3180.  
  3181. syndrome( 1 ) :- 'undist anemia'.
  3182.  
  3183. 'undist anemia' :-
  3184.    anemia( RBC ), 
  3185.    print( 'Patient has anemia. We now try to diagnose the specific type.' ),
  3186.   'anemia subtype'( RBC ).
  3187.  
  3188. 'anemia subtype'( RBC ) :-  'congenital hemolytic anemia'( RBC ).
  3189. 'anemia subtype'( RBC ) :-  'acquired hemolytic anemia'.
  3190.  
  3191. 'acquired hemolytic anemia' :-  
  3192.    ldh( high ),  nl,
  3193.    print('Based upon a diagnosis of anemia and ' ),  
  3194.    print(' high LDH we obtain acquired hemolytic anemia.' ).
  3195.  
  3196. 'congenital hemolytic anemia'( low )  :-
  3197.    'congenital hemolytic history', 
  3198.    'congenital hemolytic determinant', nl,
  3199.    print('Based upon a diagnosis of anemia and '), 
  3200.    print( 'the just named symptom we diagnose congenital hemolytic anemia.' ).
  3201.  
  3202. 'deficiency anemia' :- nl,
  3203.   print( 'Diagnosis is a deficiency anemia.' ).
  3204.  
  3205.  
  3206. 'congenital hemolytic history' :- jaundice.
  3207. 'congenital hemolytic history' :- gallstones.
  3208. 'congenital hemolytic history' :- sphenomegally.
  3209. 'congenital hemolytic history' :- hepatomegally.
  3210. 'congenital hemolytic history' :- 'bony malformations'.
  3211. 'congenital hemolytic history' :- 'mental retardation'.
  3212.  
  3213. 'congenital hemolytic determinant' :- microcytosis.
  3214. 'congenital hemolytic determinant' :- eliptocytosis.
  3215. 'congenital hemolytic determinant' :- spherocytosis.
  3216. 'congenital hemolytic determinant' :- anisopoikilocytosis.
  3217. 'congenital hemolytic determinant' :- 'anemia related to food'.
  3218.  
  3219. microcytosis :- labfindings( microcytosis ).
  3220. eliptocytosis :- labfindings( eliptocytosis ).
  3221. anisopoikilocytosis :- labfindings( anisopoikilocytosis ).
  3222. 'anemia related to food' :- evidence( 'anemia related to food' ).
  3223. spherocytosis :- nl,
  3224.      print( 'Is the % of spherocytosis > 50%' ), affirm.
  3225.  
  3226. anemia( RBC ) :- symptom( anemic ), rbc( RBC ).
  3227.  
  3228. symptom( anemic ) :- hemoglobin( low ).
  3229. symptom( anemic ) :- hematocrit( low ).
  3230.  
  3231. evidence( X ) :- nl,
  3232.   print('Has the patient evidence of '),
  3233.   print( X ), affirm.
  3234.  
  3235. labfindings( X ) :- nl,
  3236.   print('Are there laboratory findings of ' ),
  3237.   print( X ), affirm.
  3238.  
  3239. jaundice :- evidence( jaundice ).
  3240. gallstones :- evidence( gallstones ).
  3241. sphenomegally :- evidence( sphenomegally ).
  3242. hepatomegally :- evidence( hepatomegally ).
  3243. 'bony malformations' :- evidence( 'bony malformations' ).
  3244. 'mental retardation' :- evidence(  'mental retardation' ).
  3245. 'retarded growth and development' :-
  3246.      evidence( 'retarded growth and development' ).
  3247. 'crisis of viscera, bones' :-
  3248.      evidence( 'crisis of viscera, bones' ).
  3249.  
  3250.  
  3251. /* Laboratory measurements: */
  3252.  
  3253. rbc( HLN ) :- rbcmeas( RBC ), rbccat( RBC, HLN ).
  3254. rbccat( RBC, low ) :- RBC < 4.
  3255. rbccat( RBC, high) :- RBC > 6.
  3256. rbccat( RBC, norm ) :- RBC = 5.
  3257. rbcmeas(RBC) :- nl,
  3258.      print( 'Input the RBC in millions/microliter:' ),
  3259.      read( RBC ).
  3260.  
  3261. hematocrit( HLN ) :- hematocrtmeas( HEMAT ), hematcat( HEMAT, HLN ).
  3262. hematcat( HEMAT, low ) :- HEMAT < 36.
  3263. hematocrtmeas( HEMAT ) :- nl,
  3264.      print( 'What is the hematocrit level % per deciliter?:' ),
  3265.      read( HEMAT ).
  3266.  
  3267. mcv( low  ) :- mcv1( low ).
  3268. mcv( high ) :- mcv1( high ), not( arct( high ) ).
  3269.  
  3270.  
  3271. mcv1( HLN ) :- mcvmeas( MCV ), mcvcat( MCV, HLN ).
  3272. mcvcat( MCV, high) :- MCV > 96.
  3273. mcvcat( MCV, low ) :- MCV < 85.
  3274. mcvmeas( MCV ) :- nl,
  3275.   print( 'What is the level of MCV in cubic microns:' ),
  3276.   read( MCV ).
  3277.  
  3278. ldh( LDH ) :- nl,
  3279.   print( 'What is the level of LDH (high,low, or norm)?: ' ),
  3280.   read( LDH ).
  3281.  
  3282. arct( HLN ) :- arctmeas( ARCT ), arctcat( ARCT, HLN ).
  3283. arctmeas( ARCT ) :- nl,
  3284.   print( 'What is the absolute reticulocyte count in units of thousands:'),
  3285.   nl,
  3286.   read( ARCT ).
  3287.  
  3288. affirm :- nl, print( '(y./n.) ?:- ' ),  read( ANS ), nl, yes( ANS ).
  3289.  
  3290. yes( y ).
  3291. /* This is a truely silly program, since it is based on my own
  3292. medical knowledge. 
  3293. Ask: ?-itch.    or ?-lesion.    or ?-help. to get it started. */
  3294.  
  3295.  
  3296. help :- print( 'Diagnose the following topics:' ), nl, 
  3297. print( 'Itch.' ), nl, print( 'lesion' ).
  3298.  
  3299.  
  3300. itch :- print( 'Is the atmosphere dry?: ' ), 'say yes',
  3301.   print( 'Do not take so many showers. Use vaseline.' ).
  3302.  
  3303. itch :- print( 'Does the patient have an allergic history?: '), 
  3304.   'say yes', not(fever),  print( 'Consider atopic dermatitis.' ).
  3305.  
  3306. fever  :- 
  3307.   print( 'Does the patient have a fever?' ), 'say yes'.
  3308.  
  3309. 'non infective' :- acne, 'severe acne'.
  3310. 'non infective' :- acne, 'cystic acne'.
  3311. 'non infective' :- acne.
  3312. 'non infective' :- 'severe acne rosacea'.
  3313. 'non infective' :- 'rosacea'.
  3314.  
  3315. lesion :- not( fever ), 'non infective'.
  3316.  
  3317.  
  3318. acne :- 
  3319.   print( 'Is the skin oily?' ), 'say yes',
  3320.   print( 'Are there lots of pimples?' ), 'say yes',
  3321.   print( 'Condition is probably acne.' ). 
  3322.  
  3323. 'cystic acne' :- 
  3324.   print( 'Are there many yellowish cysts?' ), 'say yes', 
  3325.   print( 'Condition is cystic acne.' ).
  3326.  
  3327. 'severe acne' :- 
  3328.   print( 
  3329.     'Are there large elevated bluish abscesses with disfiguring scars?' ), 
  3330.   'say yes'.
  3331.  
  3332. 'rosacea' :- print( 'Is the patient  a woman?' ), 'say yes', 
  3333.              'acne rosacea'.
  3334.  
  3335.  
  3336. 'acne rosacea' :-  'severe'.
  3337. 'acne rosacea' :-  'mild'.
  3338.  
  3339. 'severe' :- 
  3340.   print( 'Does the patient have an enlarged nose, with growths?' ), 'say yes',
  3341.   print( 'Diagnosis is severe acne rosacea.' ).
  3342.  
  3343. 'mild' :- 
  3344.   print( 'Is the skin oily, with a tendency towards seborrhea?' ), 'say yes',
  3345.   print( 'Are there pustules surrounded by a reddish area?' ), 'say yes',
  3346.   print( 'But are they larger than ordinary acne eruptions?' ), 'say yes',
  3347.   print( 'Diagnosis is acne rosacea.' ).
  3348.  
  3349.  
  3350. 'say yes' :- read( Ans ), yes( Ans ), nl.
  3351.  
  3352.  
  3353. yes( yes ).
  3354. yes( y ).
  3355. yes( yea ).
  3356. yes( yup ).
  3357. /* 
  3358. Text substitution game.
  3359. Ask: ?-alter( [you, are, a, computer], Z ).
  3360.  
  3361. */
  3362.  
  3363. alter( [], [] ).
  3364. alter( [H|T], [X|Y] ) :- change( H, X ), alter( T, Y ).
  3365.  
  3366. change( you, i ).
  3367. change( are, [am, not ] ).
  3368. change( french, german ).
  3369. change( do, no ).
  3370. change( X, X ).
  3371.  
  3372. /* This is an unfinished expert system for rock blasting. It was orig-
  3373. inally written in another dialect and I have not had time to convert it.
  3374.  Go to work!. */
  3375.  
  3376.  
  3377.  
  3378. rock_blasting :- 
  3379.   print( 'Pleas answer each of the following questions by entering
  3380.      \na number in the form "1" or "2" or "3". etc., whichever appropriate.
  3381.      \nFor further information enter "help." or "why".' ),
  3382. (decision(X) ; X = error), !,
  3383. print( 'Based on your answers to the questions,' ),
  3384. meseg( X ).
  3385.  
  3386.  
  3387. ask( NQ, NA ) :- question( NQ ),
  3388.       answer( NA ),!,
  3389.       (NA = help, help( NQ), retry( ask( NQ, NA) ) );
  3390.       (NA = why, why( NQ ),  retry( ask(NQ,NA)   ) ).
  3391.  
  3392.  
  3393. meseg(1) :- print( 'Presplitting is feasible and recommended' ).
  3394. meseg(2) :- print( 'Presplitting is feasible but not recommended.' ).
  3395. meseg(3) :- print( 'Smooth blasting is recommended.' ).
  3396. meseg(4) :- print( 'Conventional blasting is recommended' ).
  3397. meseg(5) :- print( 'Presplitting is feasible but some experimentation     
  3398.     \nis necessary to obtain design parameters.' ).
  3399.  
  3400. meseg(error) :- print(
  3401.     '\nThere is an error in the answer to one of the questions.
  3402.     \nTo restart, type rock_blasting. Respond to each question with a 
  3403.     \nnumber in the range mentioned.' ).
  3404.  
  3405. question(1) :- print(
  3406.     '\nIs it critical to have a smooth rock surface and/or maintain the
  3407.     \nintegrity of the boundary rock?
  3408.     \n 1) Yes     2) No.' ).
  3409. help(1) :- print( 'if you don\'t care, you can just blast away.').
  3410. why(1)  :- print( 'If yes, more elaborate information is required before a 
  3411.     \ndecision can be made.' ).
  3412.  
  3413. question(2) :- print( 'Where is the blast?
  3414.     \n 1) On the surface    2) Underground' ).
  3415.         
  3416. help(2) :- print( 'Look up! Do you see sky?' ).
  3417.  
  3418. why(2) :- print( 'if on the surface, there are many options available.' ).
  3419.  
  3420. question(3) :-
  3421.     print( 'is the rock
  3422.       \n1) Hard( compressive strength > 100,000 MPa )?
  3423.       \n2) Soft( compressive strength < 100,000 MPa )?' ).
  3424.  
  3425. help(3) :- print( 'Measure the rock strength in MegaPascals.' ).
  3426. why(3) :- print( 'I don\'t know' ).
  3427.  
  3428.  
  3429. question(4) :- print( 'Is the bench height( or blasthole length ) < 50 feet?
  3430.     \n1) Yes   2) No.' ).
  3431.  
  3432. help(4) :- print( 'How deep did you make the hole?' ).
  3433. why(4) :- print( 'I don\'t know.' ).
  3434.  
  3435. question(5) :- print('Is the borehole drill capable of drilling a 2" to 4"
  3436.     \n blasthole?
  3437.     \n1) Yes      2) No.' ).
  3438.  
  3439. help(5) :- print( 'Go check the drill.' ).
  3440. why(5) :- print( 'I don\'t know' ).
  3441.  
  3442.  
  3443.  
  3444. question(6) :- print( 'Is the charge density of the explosive in the
  3445.     \nblasthole\n 1)High(>1.1 g/cc)?     2)Low(< 1.1g/cc)?' ).
  3446.  
  3447. help(6) :- print( 'go check while I hide behind a rock.' ).
  3448. why(6) :- print( 'I don\'t know.' ).
  3449.  
  3450. question(7) :- print( 'Is the rock mass
  3451.     \n1) Stratified with the proposed face parallel to the plane of
  3452.     \n the dominant fabric elements, or not
  3453.     \nstratified but heavily jointed?' ),
  3454.     print( 
  3455.     '\n\n2) Stratified and/or heavily jointed with the proposed face not
  3456.     \nparallel to the plane of the dominant fabric element?
  3457.  
  3458.     \n\n3)Jointed or fractured such that the blasting will create loose, 
  3459.     \nblocky conditions on theface?' ).
  3460.     
  3461. help(7) :- print( 'That is indeed a tough question!' ).
  3462. why(7) :- print( 'I don\'t know.' ).
  3463.  
  3464.  
  3465. question(8) :- print('Are the static field stresses
  3466.     \n1)Low( < 10 MPa ) with the principle stresses parallel,
  3467.     \nto the proposed face?
  3468.     \n\nLow( < 10MPa) but with the principle stresses parallel to
  3469.     \nthe proposed face?
  3470.     \n\n3)High( > 10 MPa )?' ).
  3471. help(8) :- print( 'That\'s a tough question' ).
  3472. why( 8) :- print( 'I don\'t know.' ).
  3473.  
  3474. decision(4) :- ask( 1,2 ).
  3475. decision(3) :- ask(1,1),ask(3,2).
  3476. decision(5) :- ask(1,1),ask(2,1),ask(3,2).
  3477. decision(4) :- ask(1,1),ask(2,1),ask(3,2).
  3478. decision(5) :- ask(1,1),ask(2,1),ask(3,1),ask(4,1),ask(5,2).
  3479. at1 :- ask(1,1),ask(2,1),ask(3,1),ask(4,1),ask(5,1).
  3480. decision(5) :- at1, ask(6,1).
  3481. decision(1) :- at1,ask(6,2),ask(7,1),ask(8,1).
  3482. decision(2) :- at1,ask(6,2),ask(7,1),ask(8,2).
  3483. decision(3) :- at1,ask(6,2),ask(7,1),ask(8,3).
  3484. decision(4)  :- at1,ask(6,2),ask(7,2).
  3485. decision(3) :- at1,ask(6,2),ask(7,3).
  3486.  
  3487.  
  3488. answer( A ) :- rnum( A ).
  3489. /*
  3490. answer(A) :- ratom( X ), conv( X, A ), !.
  3491.  
  3492. conv(X,I) :- atoi( X, I ), 0 < I, I < 4, !.
  3493. conv(X,A) :- name( X, String ), valid_resp( String, A ), !.
  3494.  
  3495.  
  3496. valid_resp( [H|T], A ) :- type_ans( H, A ).
  3497.  
  3498. type_ans( X, A ) :- ([X] = "h"; [X] = "H"), A = help.
  3499. type_ans( X, A ) :- ([X] = "w"; [X] = "W"), A = why.
  3500.  
  3501. valid_resp( [], A ) :-
  3502.     print('\nPlease try to give me a H,W, or number for an answer.'),
  3503.     answer( A ), !.
  3504.  
  3505. valid_resp( [H|T], A ) :- valid_resp( T, A ).
  3506. */
  3507.  
  3508.  
  3509.  
  3510.  
  3511.  
  3512. /* 
  3513. Note: Paula did not claim the prize of a free type VMI PROLOG
  3514. for a demonstration program. However, she is working on making
  3515. Pooh smarter, and I anticipate that she shortly will. (R.M). 
  3516. */
  3517.  
  3518.  
  3519. /* --------------- POOH : A PRO FOR THE AMATEUR --------------- */
  3520. /* -------------- Copyright 1985 Paula McKerall --------------- */
  3521.  
  3522. /* To wake pooh up, type: hello.<CR> when prompted "?-"         */
  3523. /* (Of course, type: consult(pooh).<CR> to get to his house!)   */
  3524.  
  3525. hello :- print( '\nHello! -- pooh is a program of very little brain,' ),
  3526.      print( '\nso please answer with: yes.<CR> if you mean "yes" -' ),
  3527.      print( '\nor with: no.<CR> if you mean "no" -' ),
  3528.      print( '\nor pooh will get confused!' ), nl,
  3529.      print( '\n(If you learn Prolog, you can make him smarter!)' ), nl,
  3530.      ask_want.
  3531. ask_want :- print( '\nDo you want advice about Prolog?' ), ((yes,
  3532.      ask_fun); (sorry; confused)).
  3533. ask_fun :- print( '\nDo you like to have fun?' ), ((learn; too_bad);
  3534.      confused).
  3535. learn :- yes, print( '\nThen please learn Prolog; you will like it.' ),
  3536.      print( '\nAnd then you can have a good time with pooh!' ), nl, naptime.
  3537. sorry :- no, print( '\nSorry, pooh can only give advice about Prolog.' ),
  3538.      print( '\nIf you learned Prolog, you could teach him other things!' ),
  3539.      nl, print( '\n(Besides, it is lonely in here; pooh needs a friend!)' ),
  3540.      nl, naptime.
  3541. too_bad :- no, print( '\nToo bad, because Prolog is fun.' ),
  3542.      print( '\nYou might change your mind if you try it!' ), nl,
  3543.      print( '\n(Besides, pooh is hungry, and if you learned Prolog,' ),
  3544.      print( '\nyou could teach him how to ask for honey!)' ), nl, naptime.
  3545. confused :- print( '\nPooh is most definitely confused.'  ), nl, naptime.
  3546. yes :- print( '\nPlease tell pooh: yes. or no. ?- ' ), read( yes );
  3547.      print( '\nThat is a strange answer. Do you mean yes?- '), read( yes ).
  3548. no :- print( '\nCuriouser and curiouser. Do you mean no?- ' ), read( yes );
  3549.      print( '\nPooh is getting confused. Do you mean yes?- '), read( no ).
  3550. naptime :- print( '\nPooh has to take a nap now.' ),
  3551.      print( '\nTo wake him up say: hello.<CR>' ),
  3552.      print( '\nOr to quit say: exitsys.<CR>' ).
  3553.  
  3554. /* This is really a silly little game; pooh behaves himself if you
  3555.    give him a chance, but I think it's fun to confuse him. Just don't
  3556.    make any errors in the "rules" or you'll get the Prolog error
  3557.    messenger, who is smarter than pooh but not as cuddly; unlike the
  3558.    error messenger, pooh can't say "No." *//*
  3559. Concatentate strings, using append. If the below is asked, 
  3560.  
  3561. ?-append( "ABC", "DEF", X ), append( "123", X, Y ), append( Y, "XYZ", Z ),
  3562.   printstring( Z ).
  3563.  
  3564.   you will get: Z = "123ABCDEFXYX", printed out as a list of ASCII codes. */
  3565.  
  3566. append( [], L, L ).
  3567. append( [Z|L1], L2, [Z|L3] ) :- append( L1, L2, L3 ).
  3568. printstring( [] ).
  3569. printstring( [H|T] ) :- put( H ), printstring( T ).
  3570.  
  3571.  
  3572. lips(L) :- rev( [1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,
  3573.               21,22,23,24,25,26,27,28,29,30], L ).
  3574.  
  3575. rev( [], [] ).
  3576. rev( [H|T], L ) :- rev( T,Z), append( Z, [H], L ).
  3577. /* Improved bicycle program. Ask: ?-partlist( bike ). */
  3578.  
  3579.  
  3580. basicpart( rim ).
  3581. basicpart( rearframe ).
  3582. basicpart( gears ).
  3583. basicpart( nut ).
  3584. basicpart( spoke ).
  3585. basicpart( handles ).
  3586. basicpart( bolt ).
  3587. basicpart( fork ).
  3588.  
  3589. assembly( bike, [quant( wheel, 2 ), quant( frame, 1 )] ).
  3590. assembly( wheel, [quant( spoke, 20 ), quant( rim, 1 ), quant( hub, 1)] ).
  3591. assembly( frame, [quant( rearframe, 1), quant( frontframe, 1 ) ] ).
  3592. assembly( frontframe, [quant( fork, 1 ), quant( handles, 1 )] ).
  3593. assembly( hub, [quant( gears, 1 ), quant( bolt, 7 ), quant( axle, 1 ) ] ).
  3594. assembly( axle, [quant( bolt, 1 ), quant( nut, 2) ] ).
  3595.  
  3596. partlist( T ) :- partsof( 1, T, P ), collect( P, Q ), 
  3597.   printpartlist( Q ).
  3598.  
  3599. partsof( N, X, P ) :- assembly( X, S ), partsoflist( N, S, P ).
  3600. partsof( N,X,[quant(X,N)]) :- basicpart( X ).
  3601.  
  3602. partsoflist( _, [], [] ).
  3603. partsoflist( N, [quant( X, Num) | L ], T ) :-
  3604.   M is N * Num,
  3605.   partsof( M, X, Xparts ),
  3606.   partsoflist( N, L, Restparts ),
  3607.   append( Xparts, Restparts, T ).
  3608.  
  3609. collect( [], [] ).
  3610. collect( [quant(X, N )|R], [quant( X, Ntotal)|R2] ) :-
  3611.   collectrest( X, N, R, O, Ntotal ),
  3612.   collect( O, R2 ).
  3613.  
  3614. collectrest( _, N, [], [], N ).
  3615. collectrest( X, N, [quant( X, Num)|Rest ], Others, Ntotal ) :-
  3616.   !,
  3617.   M is N + Num,
  3618.   collectrest( X, M, Rest, Others, Ntotal ).
  3619. collectrest( X,N,[Other|Rest],[Other|Others],Ntotal ) :-
  3620.   collectrest( X, N, Rest, Others, Ntotal ).
  3621.  
  3622. printpartlist( [] ).
  3623. printpartlist( [quant( X, N )|R] ) :- nl,
  3624.   print( '    ' ), print( N ), print( '     ' ), 
  3625.   print( X ), printpartlist( R ).
  3626.  
  3627. append( [], L, L ).
  3628. append( [X|L1], L2, [X|L3] ) :- append( L1, L2, L3 ).
  3629.  
  3630. /* Ask ?-aless( 2, 3 ). Get: Yes.
  3631.    Ask ?-aless( 3, 2 ). Get: No. */
  3632.  
  3633.  
  3634. aless( X, Y ) :- name( X, L ), name( Y, M ), alessx( L, M ).
  3635. alessx( [], [_|_] ).
  3636. alessx( [X|_], [Y|_] ) :- X < Y.
  3637. alessx( [P|Q], [R|S] ) :- P = R, alessx( Q, S )./* Describe the parts required to make a bicycle. Firt the elementary parts
  3638. are given (basicpart). Then a description of various subassemblies.
  3639. Ask: ?-partsof( hub, P ). to get all the basic parts required to make a hub.
  3640. Ask: ?-partsof( bike, P ). for the whole bike. */
  3641.  
  3642.  
  3643. basicpart( rim ).
  3644. basicpart( rearframe ).
  3645. basicpart( gears ).
  3646. basicpart( nut ).
  3647. basicpart( spoke ).
  3648. basicpart( handles ).
  3649. basicpart( bolt ).
  3650. basicpart( fork ).
  3651.  
  3652. assembly( bike, [quant( wheel, 2 ), quant( frame, 1 )] ).
  3653. assembly( wheel, [quant( spoke, 20 ), quant( rim, 1 ), quant( hub, 1)] ).
  3654. assembly( frame, [quant( rearframe, 1), quant( frontframe, 1 ) ] ).
  3655. assembly( frontframe, [quant( fork, 1 ), quant( handles, 1 )] ).
  3656. assembly( hub, [quant( gears, 1 ), quant( axle, 1 ) ] ).
  3657. assembly( axle, [quant( bolt, 1 ), quant( nut, 2) ] ).
  3658.  
  3659. partsof( X, [X] ) :- basicpart( X ).
  3660. partsof( X, P ) :- assembly( X, Subparts ),
  3661.                    partsoflist( Subparts, P ).
  3662.  
  3663. partsoflist( [], [] ).
  3664. partsoflist( [quant( X,N ) | Tail ], Total ) :-
  3665.              partsof( X, Headparts ),
  3666.              partsoflist( Tail, Tailparts ),
  3667.              append( Headparts, Tailparts, Total ).
  3668.  
  3669. append( [], L, L ).
  3670. append( [X|L1], L2, [X|L3] ) :- append( L1, L2, L3 ).
  3671. /* To analyze the family structure of the family of Queen Victoria.
  3672. English friend of mine notes there wasn't a Harry. I put him in.
  3673.  
  3674. Answers the compelling question: Who is X the sister of?
  3675.  
  3676. Ask: ?-sisterof( alice, X ). or ?-sisterof( alice, harry ).
  3677.  
  3678.   or ?-sisterof( alice, X ), loves( X, wine ). as an example of a
  3679.   complex question. 
  3680.  
  3681. or even:
  3682.  
  3683. sisterof( alice, X ), loves( X, wine ), loves( alice, wine ).
  3684.  
  3685. */
  3686.  
  3687. sisterof( X, Y ) :- parents( X, M, F ), 
  3688.                     female( X ),
  3689.                     parents( Y, M, F ).
  3690.  
  3691. parents( edward, victoria, albert ).
  3692. parents( harry, victoria, albert ).
  3693. parents( alice, victoria, albert ).
  3694. female( alice ).
  3695.  
  3696. loves( harry, wine ).
  3697. loves( alice, wine ).
  3698. /* Recursive member of list definition. 
  3699.  
  3700. Ask: Member( X, [a,b,c,d,e,f] ) to get successively all
  3701. the members of the given list. */
  3702.  
  3703.  
  3704. member( Y, [Y|_] ).
  3705.  
  3706. member( B, [_|C] ) :-  member( B, C ).
  3707.  
  3708.  
  3709.  
  3710. /*  
  3711. For a similar program, see Clocksin & Mellish page 165.
  3712.  
  3713. Plan a trip from place to place.
  3714.  
  3715. An appropriate question would be:
  3716.  
  3717. ?-go( darlington, workington, X ).
  3718. */
  3719.  
  3720.   append( [], L, L ).
  3721.   append( [Z|L1], L2, [Z|L3] ) :- append( L1, L2, L3 ).
  3722.   printstring( [] ).
  3723.   printstring( [H|T] ) :- put( H ), printstring( T ).
  3724.  
  3725.  
  3726.   rev( [], [] ).
  3727.   rev( [H|T], L ) :- rev( T,Z), append( Z, [H], L ).
  3728.  
  3729. /* Recursive member of list definition. 
  3730.  
  3731. Ask: Member( X, [a,b,c,d,e,f] ) to get successively all
  3732. the members of the given list. */
  3733.  
  3734.  
  3735. member( Y, [Y|_] ).
  3736.  
  3737. member( B, [_|C] ) :-  member( B, C ).
  3738.  
  3739.  
  3740. pp([H|T],I)  :-  !, J is I+3, pp(H,J), ppx(T,J), nl.
  3741. pp(X,I)  :- tab(I), print(X), nl.
  3742. ppx([],_).
  3743. ppx([H|T],I)  :-  pp(H,I),ppx(T,I).
  3744.  
  3745. /* see page 163 of CM  */
  3746.  
  3747. findall(X,G,_) :-
  3748.       asserta(found(mark)),
  3749.       G,
  3750.       asserta(found(X)),
  3751.       fail.
  3752. findall(_,_,L)  :-  collect_found([],M),!, L  =  M.
  3753. collect_found(S,L)  :-  getnext(X), !, collect_found([X|S],L).
  3754. collect_found(L,L).
  3755. getnext(X)  :-  retract(found(X)), !, X \== mark.
  3756.  
  3757. a(newcastle,carlisle,58).
  3758. a(carlisle,penrith,23).
  3759. a(darlington,newcastle,40).
  3760. a(penrith,darlington,52).
  3761. a(workington, carlisle,33).
  3762. a(workington, penrith,39).
  3763.  
  3764. /*  does ; work properly ? */
  3765.  
  3766. legalnode(X,Trail,Y) :- a(Y,X,_), (not(member(Y,Trail))).
  3767. legalnode(X,Trail,Y) :- a(X,Y,_), (not(member(Y,Trail))).
  3768.  
  3769.  
  3770. go(Start,Dest,Route) :-  go1([[Start]],Dest,R), rev(R, Route).
  3771. go1([First|Rest],Dest,First) :- First = [Dest|_].
  3772. go1([[Last|Trail]|Others],Dest,Route)  :-
  3773.       findall([Z,Last|Trail],legalnode(Last,Trail,Z),List),
  3774.       append(List,Others,NewRoutes),
  3775.       go1(NewRoutes,Dest,Route).
  3776. /*                    SIEVE OF ERASTHATONES
  3777.  
  3778.  
  3779. Ask ?-primes( 100, L ).   to get all the primes from 1 to 100
  3780. printed out as the list "L".  */
  3781.  
  3782. primes( Limit, Ps ) :- integers( 2, Limit, Is ), sift( Is, Ps ).
  3783.  
  3784. integers( Low, High, [Low|Rest] ) :-
  3785.    Low =< High, !, M is Low+1, integers(M, High, Rest ).
  3786. integers( _,_,[] ).
  3787.  
  3788. sift( [], [] ).
  3789. sift( [I|Is], [I|Ps]) :- remove(I,Is,New), sift( New, Ps ).
  3790.  
  3791. remove(P,[],[]).
  3792. remove(P,[I|Is],[I|Nis]) :-
  3793.    not( 0 is I mod P ),
  3794.    !,
  3795.    remove(P, Is, Nis).
  3796.  
  3797. remove(P,[I|Is],Nis) :- 0 is I mod P, remove(P, Is, Nis).
  3798.  
  3799.  
  3800. con_num_list( [H|T] ) :- rnum( H ), con_num_list( T ).
  3801. con_num_list( [] ).
  3802.  
  3803.  
  3804. /* To multiply a row by a column: */
  3805.  
  3806. mat_mult( [H1|T1], [H2|T2], res ) :-
  3807.     mat_mult1( [H1|T1], [H2|T2, 0, res ).
  3808.  
  3809. mat_mult1( [H1|T1], [H2|T2], sum, res ) :-
  3810.     sum is sum + H1 * H2,
  3811.     mat_mult1( T1, T2, sum, res ).
  3812.  
  3813. mat_mult1( [], [], sum, res ) :- res = sum.
  3814.  
  3815.  
  3816. /* To get the nth element of a list: 
  3817.    Let us assume a matrix in the form of a list of columns: 
  3818.  
  3819. [ L1, L2.....]
  3820.  
  3821. listel( N, [H|T], X ) :- 
  3822.     N > 0, 
  3823.     N is N - 1,
  3824.     listel( N, T, X ).
  3825.  
  3826. listel( N, [H|_], X ) :- X = H.
  3827.  
  3828. /* Below, X, Y are the "coordinates".
  3829.    L is the complex list representing the array.
  3830.    element is the returned value. */
  3831.  
  3832. matrix_el( X, Y, L, element ) :-
  3833.  
  3834. /* First get the row, represented as an element "rowel" in list L */
  3835.  
  3836.     listel( X, L, rowel ),
  3837.  
  3838. /* And now the value contained within the row. */
  3839.     listel( Y, rowel, element ).
  3840. get_answer( A ) :- 
  3841.     ratom( X ), name( X, String ),
  3842.         valid_resp( String, A ), !.
  3843.  
  3844. valid_resp( [H|T], A ) :- type_ans( H, A ).
  3845.  
  3846. type_ans( X, A ) :- ([X] = "y"; [X] = "Y"), A = yes.
  3847. type_ans( X, A ) :- ([X] = "n"; [X] = "N"), A = no.
  3848. type_ans( X, A ) :- ([X] = "w"; [X] = "W"), A = why.
  3849.  
  3850. ?-print('\nYou can start animal by typing "help.<CR>"\n' ).
  3851.  
  3852. valid_resp( [], A ) :-
  3853.     print('\nPlease try to give me a yes or no answer.'),
  3854.     get_answer( A ), !.
  3855.  
  3856. valid_resp( [H|T], A ) :- valid_resp( T, A ).
  3857.  
  3858. /*
  3859. Note: Carl is an A.D.A. PROLOG user who has contributed this program for
  3860. the enjoyment of others.
  3861.  
  3862.           Residential Air Conditioning Diagnosis System
  3863.                          by Carl Bredlau
  3864.                         909 Rahway Avenue
  3865.                    Westfield, New Jersey 07090
  3866. */
  3867.  
  3868.  
  3869. nothing(X)  :-
  3870.      print('Is there a/c (y/n)? '),
  3871.      ratom(n), !, X = running,
  3872.      asserta( (nothing(running) :- !) ).
  3873.  
  3874. nothing(X)   :-
  3875.       print('I can not diagnose this.  Will quit'), nl,
  3876.       asserta( (nothing(running) :- (!, fail)) ), fail.
  3877.  
  3878. check(thermostat_system_switch) :-
  3879.       nothing(running).
  3880.  
  3881.  
  3882. check(thermostat_fan_switch) :-
  3883.       check(thermostat_system_switch),
  3884.       switch(thermostat_system_switch,'in the cool position',yes).
  3885.       thermostat(calling).
  3886.  
  3887. check(for_air)   :-
  3888.      check(thermostat_fan_switch),
  3889.      switch(thermostat_fan_switch,on,yes),
  3890.      fan(furnace,on).
  3891.  
  3892. check(furnace_24_volts) :-
  3893.        check(thermostat_fan_switch),
  3894.        switch(thermostat_fan_switch,on,yes),
  3895.        fan(furnace,off).
  3896.  
  3897. check(furnace_110_volts) :-
  3898.     check(furnace_24_volts),
  3899.     voltage(furnace,24,no).
  3900.  
  3901. check(service_switch) :-
  3902.      check(furnace_110_volts),
  3903.      voltage(furnace,110,no).
  3904.  
  3905. check(circuit_breaker) :-
  3906.       check(service_switch),
  3907.       voltage('service switch',line,110,no).
  3908.  
  3909. check(coil_of_fan_relay) :-
  3910.       check(furnace_24_volts),
  3911.       voltage(furnace,24,yes).
  3912.  
  3913. check(fan,closed_coil_relays) :-
  3914.       check(coil_of_fan_relay),
  3915.       voltage( fan_relay_coil,24,yes).
  3916.  
  3917. check(Which,continuity_at_relay_coil) :-
  3918.       check(Which,closed_coil_relays),
  3919.       coil_contacts(Which,open).
  3920.  
  3921. check(Which,voltage_at_motor) :-
  3922.       check(Which,closed_coil_relays),
  3923.       coil_contacts(Which,closed).
  3924.  
  3925. check(Which,over_amp) :-
  3926.      check(Which,voltage_at_motor),
  3927.      motor_voltage(Which,line,yes),
  3928.      motor(Which,running,no),
  3929.      motor(Which,hot,yes),
  3930.      print( Which, 'motor has internal overload -- thermal relay kicked off'), nl,
  3931.      print( 'Cool and check for overamperage'), nl.
  3932.  
  3933. check(Which,motor_continuity) :-
  3934.      (check(Which,voltage_at_motor);
  3935.       (Which = compressor, check(continuity_at_compressor) )),
  3936.      motor_voltage(Which,line,yes),
  3937.      motor(Which,running,no),
  3938.      motor(Which,hot,no).
  3939.  
  3940. check(condensing_unit) :-
  3941.     check(for_air),
  3942.     air(yes),
  3943.     switch(system_cooling_switch,on,yes).
  3944.  
  3945. check(condenser_24_volts) :-
  3946.     check(condensing_unit),
  3947.     fan(condenser,off),
  3948.     voltage(condenser,220,yes).
  3949.  
  3950. check(condensing_unit_breaker) :-
  3951.      check(condensing_unit),
  3952.      fan(condenser,off),
  3953.      voltage(condenser,220,no),
  3954.      switch(disconnect,on,yes).
  3955.  
  3956. check(compressor_contactor_coil) :-
  3957.      check(condenser_24_volts),
  3958.      voltage(condenser,24,yes).
  3959.  
  3960. check(condenser,closed_coil_relays) :-
  3961.      check(compressor_contactor_coil),
  3962.      voltage(compressor_contactor_coil,24,yes),
  3963.      safeties(yes).
  3964.  
  3965. check(compressor_voltage) :-
  3966.      check(condensing_unit),
  3967.      fan(condenser,on),
  3968.      voltage(condenser,220,yes),
  3969.      voltage(condenser,24,yes),
  3970.      coil_contacts(compressor,closed),
  3971.      motor(compressor,running,no).
  3972.  
  3973. check(compressor_internals_overload) :-
  3974.      check(compressor_voltage),
  3975.      motor_voltage(compressor,line,yes).
  3976.  
  3977.  
  3978. check(continuity_at_compressor) :-
  3979.      check(compressor_internals_overload),
  3980.      coil_contacts(compressor_internals,closed).
  3981.  
  3982. check(gauges) :-
  3983.      check(condensing_unit),
  3984.      fan(condenser,on),
  3985.      voltage(condenser,220,yes),
  3986.      voltage(condenser,24,yes),
  3987.      coil_contacts(compressor,closed),
  3988.      motor(compressor,running,yes),
  3989.      gauge(X).
  3990.  
  3991.  
  3992.  
  3993.  
  3994. diagnosed(burned_out_transformer) :-
  3995.         check(furnace_110_volts),
  3996.         voltage(furnace,110,yes),
  3997.         print('Transformer burned out. Replace transformer'),nl.
  3998.  
  3999.  
  4000. diagnosed(repair_line_voltage_wire) :-
  4001.        check(service_switch),
  4002.        voltage('service switch',lOad,110,yes),
  4003.        print( 'Repair line voltage wire'), nl.
  4004.  
  4005.  
  4006. diagnosed(replace_service_switch) :-
  4007.         check(service_switch),
  4008.         voltage('service switch',lOad,110,no),
  4009.         voltage('service switch',line,110,yes),
  4010.         print( 'Replace service switch if switch is on'), nl,
  4011.         print( 'Otherwise, turn on switch'), nl.
  4012.  
  4013. diagnosed(replace_circuit_breaker) :-
  4014.         check(circuit_breaker),
  4015.         voltage('circuit breaker',lOad,110,no),
  4016.         voltage('circuit breaker',line,110,yes),
  4017.         breaker(circuit,on),
  4018.         print( 'Replace circuit breaker' ), nl.
  4019.  
  4020. diagnosed(repair_circuit_wire) :-
  4021.         check(circuit_breaker),
  4022.         voltage( 'service switch',line,110,no),
  4023.         voltage( 'circuit breaker',lOad,110,yes),
  4024.         print( 'Repair wire between circuit breaker and switch'),
  4025.         nl.
  4026.  
  4027. diagnosed(breaker_switch) :-
  4028.          check(circuit_breaker),
  4029.          breaker(circuit,off),
  4030.          print( 'Please turn on the breaker'), nl.
  4031.  
  4032. diagnosed(check_for_grounds) :-
  4033.         check(circuit_breaker),
  4034.         breaker(circuit,tripped),
  4035.         print('Check for grounded load'), nl,
  4036.         print('i.e., motor, relay, transformer, burnt ground wire'),nl.
  4037.  
  4038. diagnosed(replace_subbase) :-
  4039.        check(coil_of_fan_relay),
  4040.        voltage( fan_relay_coil,24,no),
  4041.        print('Jump R to G at thermostat'),nl,
  4042.        fan_turns(furnace,yes),
  4043.        print('Replace subbase of thermostat'), nl.
  4044.  
  4045.  
  4046. diagnosed(replace_therm_wire) :-
  4047.        check(coil_of_fan_relay),
  4048.        voltage( fan_relay_coil,24,no),
  4049.        fan_turns(furnace,no),
  4050.        print('Look for open wire between thermostat and subbase'), nl.
  4051.  
  4052. diagnosed([Which,replace_relay]) :-
  4053.       check(Which,continuity_at_relay_coil),
  4054.       continuity(Which,no),
  4055.       print( 'Replace ',Which, ' relay'), nl.
  4056.  
  4057. diagnosed([Which,replace_relay]) :-
  4058.       check(Which,continuity_at_relay_coil),
  4059.       continuity(Which,yes),
  4060.       print( 'Check for mechanical failure and replace ',Which, ' relay'), nl.
  4061.  
  4062. diagnosed([Which,repair_wire]) :-
  4063.      check(Which,voltage_at_motor),
  4064.      motor_voltage(Which,line,no),
  4065.      print( 'Repair wire between relay and ',Which,'?'), nl.
  4066.  
  4067. diagnosed([Which,replace_motor_or_adjust_pulley]) :-
  4068.      check(Which,over_amp),
  4069.      motor(Which,over_amperage,yes),
  4070.      print( 'With direct drive replace motor.'),nl,
  4071.      print( 'With pulley drive adjust pulley to proper amperage'),nl.
  4072.  
  4073. diagnosed([Which,replace_motor]) :-
  4074.      check(Which,motor_continuity),
  4075.      continuity(Which,no),
  4076.      print('Replace ',Which,' motor'),nl.
  4077.  
  4078. diagnosed([Which,look_at_capacitor]) :-
  4079.      check(Which,motor_continuity),
  4080.      continuity(Which,yes),
  4081.      motor(Which,hum,yes),
  4082.      print('Look at the ',Which,' motor capacitor'),nl.
  4083.  
  4084. diagnosed(dirty_stuff) :-
  4085.      check(for_air),
  4086.      air(no),
  4087.      maintenance(List),
  4088.      perform_maintenance(List).
  4089.  
  4090. diagnosed(replace_thermostat) :-
  4091.     check(condenser_24_volts),
  4092.     voltage(condenser,24,no),
  4093.     print('Jump out R to Y at thermostat'),
  4094.     fan_turns(condenser,yes),
  4095.     print('Replace thermostat'), nl.
  4096.  
  4097. diagnosed(repair_condenser_wire) :-
  4098.     check(condenser_24_volts),
  4099.     voltage(condenser,24,no),
  4100.     fan_turns(condenser,no),
  4101.     print('Repair wire between thermostat and condenser'),nl,
  4102.     print('Check 24 volt source'),nl.
  4103.  
  4104.  
  4105.  
  4106. diagnosed(replace_condensing_unit_breaker) :-
  4107.         check(condensing_unit_breaker),
  4108.         voltage('condensing unit breaker',lOad,110,no),
  4109.         voltage('condensing unit breaker',line,110,yes),
  4110.         breaker(condensing_unit,on),
  4111.         print( 'Replace condensing unit breaker' ), nl.
  4112.  
  4113. diagnosed(repair_condensing_unit_wire) :-
  4114.         check(condensing_unit_breaker),
  4115.         voltage( 'condensing unit breaker',lOad,110,yes),
  4116.         print( 'Repair wire between condensing unit breaker and switch'),
  4117.         nl.
  4118.  
  4119. diagnosed(condensing_unit_switch) :-
  4120.          check(condensing_unit_breaker),
  4121.          breaker(condensing_unit,off),
  4122.          print( 'Please turn on the condensing unit breaker'), nl.
  4123.  
  4124.  
  4125. diagnosed(check_for_condensing_unit_grounds) :-
  4126.         check(condensing_unit_breaker),
  4127.         breaker(condensing_unit,tripped),
  4128.         print('Check for grounded load'), nl,
  4129.         print('i.e., motor, relay, transformer, burnt ground wire'),nl.
  4130.  
  4131.  
  4132. diagnosed(safeties_open) :-
  4133.      check(compressor_contactor_coil),
  4134.      voltage(compressor_contactor_coil,24,no),
  4135.      safeties(no),
  4136.      print('Check safeties'),nl.
  4137.  
  4138. diagnosed(compressor_contactor) :-
  4139.      check(compressor_voltage),
  4140.      motor_voltage(compressor,line,no),
  4141.      print('Check for contactor problem or wire open'), nl.
  4142.  
  4143. diagnosed(refrigerant_charge) :-
  4144.      check(compressor_internals_overload),
  4145.      coil_contacts(compressor_internals,open),
  4146.      motor(compressor,hot,yes),
  4147.      print( 'Cool and check refrigerant charge'), nl.
  4148.  
  4149. diagnosed(replace_compressor) :-
  4150.      check(compressor_internals_overload),
  4151.      coil_contacts(compressor_internals,open),
  4152.      motor(compressor,hot,no),
  4153.      print( 'Replace compressor'), nl.
  4154.  
  4155. diagnosed(defective_condenser_fan) :-
  4156.      check(condensing_unit),
  4157.      fan(condenser,off),
  4158.      voltage(condenser,220,yes),
  4159.      voltage(condenser,24,yes),
  4160.      coil_contacts(compressor,closed),
  4161.      motor(compressor,running,yes),
  4162.      print('Defective condenser fan'),nl.
  4163.  
  4164. diagnosed(leak) :-
  4165.     check(gauges),
  4166.     pressure(high,High),
  4167.     pressure(low,Low),
  4168.     Low = 0, High = 0,
  4169.     print('Find leak, repair, and recharge'),nl.
  4170.  
  4171. diagnosed(replace_compressor) :-
  4172.     check(gauges),
  4173.     pressure(high,High),
  4174.     pressure(low,Low),
  4175.     60 =< Low, Low =< 90,
  4176.     60 =< High, High =< 90,
  4177.     Diff is High - Low,
  4178.     Diff =< 10,
  4179.     motor(compressor,drawing_amperage,yes),
  4180.     print('Pressures are almost equal.  Replace compressed'),nl.
  4181.  
  4182. diagnosed(low_pressure) :-
  4183.     check(gauges),
  4184.     pressure(low,Low),
  4185.     Low =< 40,
  4186.     print('(1) Check for lack of maintenance on inside'), nl,
  4187.     maintenance(X),
  4188.     print_maintenance_start(X),
  4189.     print('(2) short of coolant'), nl,
  4190.     print('(3) restriction in refrigerant line'), nl,
  4191.     print('(4) expansion valve problem'), nl.
  4192.  
  4193. diagnosed(high_pressure) :-
  4194.     check(gauges),
  4195.     pressure(high,High),
  4196.     High >= 300,
  4197.     print('(1) Lack of maintenance on outside : compressor plugged'),nl,
  4198.     print('(2) Overcharged unit'),nl.
  4199.  
  4200.  
  4201. diagnosed(compressor_valve) :-
  4202.     check(gauges),
  4203.     pressure(low,Low),
  4204.     pressure(high,High),
  4205.     65 =< Low, Low =< 70,
  4206.     220 =< High, High =< 280,
  4207.     maintenance(X),
  4208.     print_maintenance_start(X),
  4209.     motor(compressor,low_amperage,yes),
  4210.     print('Possible broken compressor valve. Replace'),nl.
  4211.  
  4212.  
  4213. diagnosed(replace_compressor) :-
  4214.     check(gauges),
  4215.     pressure(low,Low),
  4216.     pressure(high,High),
  4217.     65 =< Low, Low =< 70,
  4218.     220 =< High, High =< 280,
  4219.     maintenance(X),
  4220.     print_maintenance_start(X),
  4221.     motor(compressor,high_amperage,yes),
  4222.     print('Compressor worn out. Replace'), nl.
  4223.  
  4224.  
  4225.  
  4226.  
  4227. possibilities( [
  4228.      burned_out_transformer,
  4229.      replace_service_switch,
  4230.      repair_line_voltage_wire,
  4231.      replace_circuit_breaker,
  4232.      repair_circuit_wire,
  4233.      breaker_switch,
  4234.      check_for_grounds,
  4235.      replace_subbase,
  4236.      repair_therm_wire,
  4237.      [fan,replace_relay],
  4238.      [fan,repair_wire],
  4239.      [fan,replace_motor_or_adjust_pulley],
  4240.      [fan,replace_motor],
  4241.      [fan,look_at_capacitor],
  4242.      dirty_stuff,
  4243.      replace_thermostat,
  4244.      repair_condenser_wire,
  4245.      replace_condensing_unit_breaker,
  4246.      repair_condensing_unit_wire,
  4247.      condensing_unit_switch,
  4248.      check_for_condensing_unit_grounds,
  4249.      safeties_open,
  4250.      [condenser,replace_relay],
  4251.      [condenser,repair_wire],
  4252.      [condenser,replace_motor_or_adjust_pulley],
  4253.      [condenser,replace_motor],
  4254.      [condenser,look_at_capacitor],
  4255.      compressor_contactor,
  4256.      refrigerant_charge,
  4257.      replace_compressor,
  4258.      [compressor,replace_motor],
  4259.      [compressor,look_at_capacitor],
  4260.      defective_condenser_fan,
  4261.      leak,
  4262.      low_pressure,
  4263.      high_pressure,
  4264.      compressor_valve
  4265.   ]).
  4266.  
  4267. begin :-
  4268.     print('Expert a/c system'), nl,
  4269.     possibilities(X),
  4270.     begin1(X).
  4271.  
  4272. begin1([]) :-
  4273.     print('Seems I could not find the problem'), nl,
  4274.     print('Better luck next time'), !.
  4275.  
  4276. begin1([H|T]) :-
  4277.        diagnosed(H), ! ,
  4278.        print('We diagnosed ',H), nl,
  4279.        print('I hope that this is it'), nl.
  4280.  
  4281. begin1([H|T]) :-
  4282.        !, begin1(T).
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288. switch(Switch,How,YesNo) :-
  4289.         print('Is the ',Switch,' ',How,' (y/n)? '),
  4290.         ratom(y),
  4291.         !,
  4292.         asserta( (switch(Switch,How,Y) :- (!, Y = yes)) ),
  4293.         YesNo = yes.
  4294.  
  4295. switch(Switch,How,YesNo) :-
  4296.         print('Please turn on the ',Switch, ' now'), nl,
  4297.         asserta( (switch(Switch,How,Y) :- (!, Y = yes)) ),
  4298.         YesNo = yes.
  4299.  
  4300. thermostat(X) :-
  4301.         print('Is the thermostat calling (y/n)? '),
  4302.         ratom(y),
  4303.         !,
  4304.         asserta( (thermostat(Y) :- (!, Y = calling)) ),
  4305.         X = calling.
  4306.  
  4307. thermostat(X) :-
  4308.         print('Please make call for cooling'),
  4309.         asserta( (thermostat(Y) :- (!, Y = calling)) ),
  4310.         X = calling.
  4311.  
  4312. fan(Which,OnOff) :-
  4313.         print('Do you hear the ',Which,' fan (y/n)? '),
  4314.         ratom(y),
  4315.         !,
  4316.         asserta( (fan(Which,Y) :- (!, Y = on)) ),
  4317.         OnOff = on.
  4318.  
  4319. fan(Which,OnOff) :-
  4320.         asserta( (fan(Which,Y) :- (!, Y = off)) ),
  4321.         OnOff= off.
  4322.  
  4323. voltage(X,Y,Volts,Z)   :-
  4324.        print( 'Is there ', Volts, ' volts on the ',
  4325.        Y, ' side of the ',
  4326.        X, ' (y/n)?  '),
  4327.        ratom(y),
  4328.        !,
  4329.        asserta( (voltage(X,Y,Volts,W) :- (!, W = yes)) ),
  4330.        Z = yes.
  4331.  
  4332. voltage(X,Y,Volts,Z)   :-
  4333.        asserta( (voltage(X,Y,Volts,W) :- (!, W = no)) ),
  4334.        Z = no.
  4335.  
  4336. voltage(X,Volts,Z)   :-
  4337.        print( 'Is there ', Volts, ' volts at the ',
  4338.        X, '? (y/n) '),
  4339.        ratom(y),
  4340.        !,
  4341.        asserta( (voltage(X,Volts,W) :- (!, W = yes)) ),
  4342.        Z = yes.
  4343.  
  4344. voltage(X,Volts,Z)   :-
  4345.        asserta( (voltage(X,Volts,W) :- (!, W = no)) ),
  4346.        Z = no.
  4347.  
  4348. motor_voltage(X,Volts,Z)   :-
  4349.        print( 'Is there ', Volts, ' volts at the ',
  4350.        X, ' motor? (y/n) '),
  4351.        ratom(y),
  4352.        !,
  4353.        asserta( (motor_voltage(X,Volts,W) :- (!, W = yes)) ),
  4354.        Z = yes.
  4355.  
  4356. motor_voltage(X,Volts,Z)   :-
  4357.        asserta( (motor_voltage(X,Volts,W) :- (!, W = no)) ),
  4358.        Z = no.
  4359.  
  4360.  
  4361.  
  4362.  
  4363. breaker(Which,X)  :-
  4364.         print('Is the ',X,' breaker tripped (y/n)? '),
  4365.         ratom(y),
  4366.         !,
  4367.         asserta( (breaker(Which,Y) :- (!, Y = tripped)) ),
  4368.         X = tripped.
  4369.  
  4370. breaker(Which,X)  :-
  4371.      print('Is the breaker on (y/n)'),
  4372.      ratom(y),
  4373.      !,
  4374.      asserta( (breaker(Which,Y) :- (!, Y = on)) ),
  4375.      X = on.
  4376.  
  4377.  
  4378. breaker(Which,X)  :-
  4379.      asserta( (breaker(Which,Y) :- (!, Y = off)) ),
  4380.      X = off.
  4381.  
  4382. fan_turns(Which,X) :-
  4383.         print('Does the ',Which, ' fan turn now (y/n)? '),
  4384.         ratom(y),
  4385.         !,
  4386.         asserta( (fan_turns(Which,Y) :- (!, Y = yes)) ),
  4387.         X = yes.
  4388.  
  4389. fan_turns(Which,X) :-
  4390.         asserta( (fan_turns(Which,Y) :- (!, Y = no)) ),
  4391.         X = no.
  4392.  
  4393.  
  4394. coil_contacts(Which,X)  :-
  4395.      print('Are the ',Which, ' contacts open (y/n)? '),
  4396.      ratom(y),
  4397.      !,
  4398.      asserta( (coil_contacts(Which,Y) :- (!, Y = open)) ),
  4399.      X = open.
  4400.  
  4401. coil_contacts(Which,X)  :-
  4402.      asserta( (coil_contacts(Which,Y) :- (!, Y = closed)) ),
  4403.      X = closed.
  4404.  
  4405.  
  4406. continuity(Device,YesNo) :-
  4407.         print('Is there continuity at the ',Device,' (y/n)? '),
  4408.         ratom(y),
  4409.         !,
  4410.         asserta( (continuity(Device,Y) :- (!, Y = yes)) ),
  4411.         YesNo = yes.
  4412.  
  4413. continuity(Device,YesNo) :-
  4414.         asserta( (continuity(Device,Y) :- (!, Y = no)) ),
  4415.         YesNo = no.
  4416.  
  4417. motor(Which,How,YesNo) :-
  4418.         print('Is the ',Which, ' motor ',How,' (y/n)? '),
  4419.         ratom(y),
  4420.         !,
  4421.         asserta( (motor(Which,How,Y) :- (!, Y = yes)) ),
  4422.         YesNo = yes.
  4423.  
  4424. motor(Which,How,YesNo) :-
  4425.         asserta( (motor(Which,How,Y) :- (!, Y = no)) ),
  4426.         YesNo = no.
  4427.  
  4428. air(X)  :-
  4429.         print('Do you hear any air (y/n)? '),
  4430.         ratom(y),
  4431.         !,
  4432.         asserta( (air(Y) :- (!, Y = yes)) ),
  4433.         X = yes.
  4434.  
  4435. air(X) :-
  4436.         asserta( (air(Y) :- (!, Y = no)) ),
  4437.         X = no.
  4438.  
  4439. perform_maintenance([]) :- !.
  4440. perform_maintenance([[Symptom,Action] | Tail]) :-
  4441.      do_maintenance(Symptom,Action),
  4442.      perform_maintenance(Tail).
  4443.  
  4444. do_maintenance(Symptom,Action) :-
  4445.      print('Is there a ',Symptom,'? (y/n)'),
  4446.      ratom(y), !,
  4447.      print(Action),nl.
  4448. do_maintenance(Symptom,Action).
  4449.  
  4450. maintenance( [
  4451.      [plugged_filter, replace],
  4452.      [broken_or_loose_belt, replace],
  4453.      [plugged_coil, clean],
  4454.      [dirty_blower_wheel, clean],
  4455.      [plugged_return_grill, clean],
  4456.      [closed_grill,open],
  4457.      [plugged_grill,clean] ]).
  4458.  
  4459.  
  4460.  
  4461. check_safeties([],Num) :- !, Num is 0.
  4462. check_safeties([[Safety,Action] | Tail], Num) :-
  4463.      ! ,
  4464.      check_safety(Safety,Action,Num1),
  4465.      check_safeties(Tail, Num2),
  4466.      Num is Num1 + Num2.
  4467.  
  4468. check_safety(Safety,Action, Num) :-
  4469.      print('Is the ',Safety,' safety open (y/n)?'),
  4470.      ratom(y), !,
  4471.      print(Action) ,nl,
  4472.      Num is 1.
  4473.  
  4474. check_safety(Symptom,Action,Num ) :- Num is 0.
  4475.  
  4476. safety_list( [
  4477.      [high_pressure,
  4478.        'Check for clogged condenser coils, condenser fan motor problem, overcharged unit'],
  4479.      [low_pressure,'Check for loss of refrigerant'],
  4480.      [compressor_internal,
  4481.        'Low refrigerant charge, expansion valve problems, filters, belts coils, compressor amperage']
  4482.            ]).
  4483.  
  4484. safeties(X)  :-
  4485.         safety_list(List),
  4486.         check_safeties(List,Num),
  4487.         Num = 0,
  4488.         !,
  4489.         asserta( (safeties(Y) :- (!, Y = yes)) ),
  4490.         X = yes.
  4491.  
  4492. safeties(X) :-
  4493.         asserta( (safeties(Y) :- (!, Y = no)) ),
  4494.         X = no.
  4495.  
  4496.  
  4497. gauge(X) :-
  4498.         print('Install gauges'), nl,
  4499.         asserta(( gauge(X) :- !)).
  4500.  
  4501.  
  4502. pressure(HighLowSide,Pounds) :-
  4503.         print('What is the pressure on the ',HighLowSide,' (end # with .)? '),
  4504.         read(Pounds),
  4505.         asserta((pressure(HighLowSide,Pounds) :- !)).
  4506.  
  4507.  
  4508.  
  4509. print_maintenance_start(X) :-
  4510.     print('Be sure that the maintenance has been done first'), nl,
  4511.     print_maintenance(X),
  4512.     asserta( (print_maintenance_start(Y) :- !) ).
  4513.  
  4514.  
  4515. print_maintenance([]) :- !.
  4516. print_maintenance([Head | Tail] ) :-
  4517.     print('     '),
  4518.     Head = [Symptom, Stuff], print(Symptom),nl,
  4519.     print_maintenance(Tail).
  4520.  
  4521.  
  4522.  
  4523.  
  4524.  
  4525.  
  4526.  
  4527. /*
  4528. Note: Carl is an A.D.A. PROLOG user who has contributed this program for
  4529. the enjoyment of others. 
  4530.  
  4531.                  Towers of Hanoi by Carl Bredlau
  4532.                         909 Rahway Avenue
  4533.                    Westfield, New Jersey 07090
  4534. */
  4535.  
  4536.  
  4537. %   stuff for prolog 86
  4538. %   print is changed to prin
  4539.  
  4540. put(X) :- ascii(C,X), putc(C).
  4541.  
  4542. makelist(1,[1]).
  4543. makelist(N, [N|Y]) :- N1 is N - 1, makelist(N1,Y).
  4544.  
  4545. biggie(1,X,[X]).
  4546. biggie(N,X,[X|Z]) :- N1 is N - 1, X1 is X + 1, biggie(N1,X1,Z).
  4547.  
  4548. alist(N,Y) :- biggie(N,1,Y).
  4549.  
  4550. %/* get the size of a list  */
  4551.  
  4552. size([],0) :-  !.
  4553. size([_|X],Num) :- size(X,N1), Num is N1 + 1.
  4554.  
  4555. %/* Might as well keep track of the disks on the poles.  This is
  4556. %   not really necessary; all we need to know is how many
  4557. %   disks are on a pole  */
  4558.  
  4559.  
  4560.  
  4561. readtop(N,Y)  :- retract(pole(N,[Y|X])), asserta(pole(N,X)).
  4562.  
  4563. writetop(N,Y) :- retract(pole(N,X)),  asserta(pole(N,[Y|X])).
  4564.  
  4565. makepoles(N) :- alist(N,Y), asserta( pole(1,Y)),
  4566.                 asserta(pole(2,[])), asserta(pole(3,[])).
  4567.  
  4568. %/* stuff for pretty printing   */
  4569. %/* Note: the CONFIG.SYS file must contain the line ANSI.SYS.  Also,
  4570. %   the ANSI.SYS file must be on the disk when the system is booted     */
  4571.  
  4572. out(X) :- put(27), prin(X).
  4573. clear  :- out('[2J'). % /* clear screen */
  4574.  
  4575. goto(X,Y)  :- put(27),prin('[',X),put(59),prin(Y,'H').  % /* 59 is ; */
  4576.  
  4577.  
  4578. stuff(1,X) :- prin(X), !.
  4579. stuff(N,X) :- prin(X), N1 is N - 1, stuff(N1,X).
  4580.  
  4581.  
  4582.  
  4583. newhanoi(1,A,B,C) :- move(1,A,B).
  4584. newhanoi(N,A,B,C) :- !,  N1 is N - 1,
  4585.                        newhanoi(N1,A,C,B),
  4586.                        move(N,A,B),
  4587.                        newhanoi(N1,C,B,A).
  4588.  
  4589.  
  4590.  
  4591. %/*  As mentioned earlier size and readtop are not really needed,
  4592. %    but I threw them in so that you can see what's there.             */
  4593.  
  4594. move(N,A,B)  :- !,   pole(A,Adisk), size(Adisk,ANum),readtop(A,N),
  4595.                    X1 is 20 - ANum, Y1 is 5 + (A - 1)* 15,
  4596.                    goto(X1,Y1), stuff(N,' '),
  4597.                    writetop(B,N), pole(B,Bdisk), size(Bdisk,BNum),
  4598.                    X2 is 20 - BNum, Y2 is 5 + (B - 1)* 15,
  4599.                    goto(X2,Y2), stuff(N,'*'),
  4600.                    goto(24,1),
  4601.                    prin('Move disk ',N,' from ',A,' to ',B,'         ').
  4602.  
  4603.  
  4604. firstpole(N,1)  :- X1 is 20 - N, goto(X1,5),
  4605.                    stuff(1,'*'), !.
  4606.  
  4607. firstpole(N,L) :-  X1 is (20 - N) + (L - 1), goto(X1,5),
  4608.                    stuff(L,'*'),
  4609.                    L1 is L - 1, firstpole(N,L1).
  4610.  
  4611.  
  4612.  
  4613. start :- prin('How many disks? '), read(N), clear, firstpole(N,N),
  4614.             makepoles(N), newhanoi(N,1,2,3), !.
  4615.  
  4616.  
  4617.  
  4618.  
  4619. factor(0,Y) :- Y is 1, !.
  4620. factor(X,Y) :- Z is X - 1, factor(Z,W), Y is X*W.
  4621.  
  4622. %/* recursive version a n! and towers of hanoi  */
  4623. hanoi(1,A,B,C) :- prin('Move disk ',1,' from ',A,' to ',B),nl, !.
  4624. hanoi(N,A,B,C) :-   N1 is N - 1,
  4625.                     hanoi(N1,A,C,B), !,
  4626.                     prin('Move disk ',N,' from ',A,' to ',B), nl,
  4627.                     hanoi(N1,C,B,A), !.
  4628.  
  4629.  
  4630.  
  4631.  
  4632.  
  4633.  
  4634.  
  4635.  
  4636.  
  4637.  
  4638.  
  4639.  
  4640.  
  4641.  
  4642. s(X,Y) :- X1 is X + 1, (Y is X1 ; s(X1,Y) ).
  4643.  
  4644. s1(X,Y) :- X1 is X + 1, Y is X + 1.
  4645. s1(X,Y) :- X1 is X + 1, s1(X1, Y).
  4646. list1(X) :- clause(X,Y),output_clause(X,Y),
  4647.         write( '.' ), nl, fail.
  4648.  
  4649. list1(X).
  4650.  
  4651. output_clause(X,true) :- !, write(X).
  4652. output_clause(X,Y)    :- write( (X :- Y) ).
  4653.  
  4654. a( b ).
  4655. a( c ).
  4656. outputclause(X,true) :- !, write(X).
  4657. outputclause(X,Y)    :- write( (X :- Y) ).go  :- 
  4658.     repeat,
  4659.     print( 'Enter a number: ' ),
  4660.     get0( Num ), nl,
  4661.         (
  4662.           ( (Num > 58), print( 'You did not enter a number'),
  4663.                 nl, fail)
  4664.           ;
  4665.           (print( 'Do it over, please. ' ), nl, fail )
  4666.         ).
  4667.                        /* Sorting Lists */
  4668.  
  4669. /*
  4670. The order predicate determines how you would like the list to be ordered:
  4671. */
  4672.  
  4673. order( A, B ) :- A > B.
  4674.  
  4675. /* The bubble sort. Invoke as ?-busort( [1,2,3], Sortlist ).
  4676. The answer is instantiated as the sorted list. */
  4677.  
  4678. busort( L, S ) :-
  4679.     append( X, [A, B|Y], L ),
  4680.     order( A, B ),
  4681.     append( X, [B,A|Y], M ),
  4682.     busort( M, S ).
  4683. busort( L, L ).
  4684.  
  4685. /* Used by most sorting algorithms. */
  4686. append( [], L, L ).
  4687. append( [H|T], L, [H|V] ) :- append( T, L, V ).
  4688.  
  4689.  
  4690. /* The quick sort. */
  4691.  
  4692.  
  4693. quisort( [H|T], S ) :-
  4694.     split( H, T, A, B ),
  4695.     quisort( A, A1 ),
  4696.     quisort( B, B1 ),
  4697.     append( A1, [H|B1], S ).
  4698.  
  4699. /* This important clause was left out by Clocksin and Mellish: */
  4700. quisort( [], [] ).
  4701.  
  4702. /* List splitting predicates used by both quick sort algorithms: */
  4703.  
  4704. split( H, [A|X], [A|Y], Z ) :- order( A, H ), split( H, X, Y, Z ).
  4705. split( H, [A|X], Y, [A|Z] ) :- order( H, A ), split( H, X, Y, Z ).
  4706. split( _, [], [], [] ).
  4707.  
  4708.  
  4709. /* 
  4710. A compact form of the quick sort. 
  4711. Invoke as: ?-quisort( List, Sortlist, [] ).
  4712. */
  4713.  
  4714. quisortx( [H|T], S, X ) :-
  4715.     split( H, T, A, B ), 
  4716.     quisortx( A, S, [H|Y] ),
  4717.     quisortx( B, Y, X ).
  4718. quisortx( [], X, X ).
  4719.  
  4720.  
  4721. /*
  4722. The insertion sort:
  4723. Invoke as ?-insort( List, Sortlist ).
  4724. */
  4725. insort( [], [] ).
  4726. insort( [X|L], M ) :- insort( L, N ), insortx( X, N, M ).
  4727.  
  4728. insortx( X, [A|L], [A|M] ) :- order( A, X ), !, insortx( X, L, M ).
  4729. insortx( X, L, [X|L] ).
  4730.  
  4731.  
  4732. insort( [], [], _ ).
  4733. insort( [X|L], M, O ) :- insort( L, N, O ), insortx( X, N, M, O ).
  4734.  
  4735.  
  4736. /* 
  4737. This form of the insertion sort needs no sort parameter.
  4738. O is instantiated to a predicate or operator which orders the elements.
  4739. Invoke as: insort( List, Sortlist, <order> ).
  4740. For instance, ?-insort( List, Sortlist, < ).
  4741. */
  4742.  
  4743. insortb( [], [], _).
  4744. insortb( [X|L], M, O ) :- insortb( L, N, O ), insortxb( X, N, M, O ).
  4745.  
  4746.  
  4747. insortxb( X, [A|L], [A|M], O ) :-
  4748.     P =.. [ O, A, X ],
  4749.     P,
  4750.     !,
  4751.     insortxb( X, L, M, O ).
  4752. insortxb( X, L, [X|L], O ).
  4753. /* 
  4754. This program performs symbolic differentiation. 
  4755.  
  4756. Sample forms to differentiate:
  4757.  
  4758.   ?-d(x+1,x,X).
  4759.   ?-d(x*x-2,x,X).
  4760.  
  4761. See C & M for more on this. 
  4762. */
  4763.  
  4764.  
  4765. ?-op( 9, fx, '%' ).
  4766.  
  4767. d(X,X,1) :- !.
  4768. d(C,X,0) :- atomic(C).
  4769. d(%U, X, %A) :- d( U, X, A ).
  4770. d( U+V, X, A+B) :- d(U,X,A), d(V,X,B).
  4771. d( U-V, X, A-B ) :- d(U,X,A), d(V,X,B).
  4772. d(C*U,X,C*A) :- atomic(C), C \= X, d(U,X,A), !.
  4773. d(U*V,X,B*U+A*V) :- d(U,X,A), d(V,X,B).
  4774. d(U/V,X,A) :- d(U*V**(%1),X,A).
  4775. d(U**V,X,V*W*U**(V-1)) :- atomic(V), c \= X, d(U,X,W).
  4776. d(log(U),X,A*U**(%1)) :- d(U,X,A).
  4777.  
  4778. /*   This is a sample network path finding algorithm.  To make use of this 
  4779. see CM (second edition) pages 168-169.  You can make use of "look" */
  4780.  
  4781.   append( [], L, L ).
  4782.   append( [Z|L1], L2, [Z|L3] ) :- append( L1, L2, L3 ).
  4783.   printstring( [] ).
  4784.   printstring( [H|T] ) :- put( H ), printstring( T ).
  4785.  
  4786.  
  4787.   rev( [], [] ).
  4788.   rev( [H1|TT], L1 ) :- rev( TT,ZZ), append( ZZ, [H1], L1 ).
  4789.  
  4790. /* Recursive member of list definition. 
  4791.  
  4792. Ask: Member( X, [a,b,c,d,e,f] ) to get successively all
  4793. the members of the given list. */
  4794.  
  4795.  
  4796. mem( YY, [YY|_] ).
  4797. mem( B, [_|C] ) :-  mem(B, C ).
  4798.  
  4799. pp([H|T],I)  :-  !, J is I+3, pp(H,J), ppx(T,J), nl.
  4800. pp(X,I)  :- tab(I), print(X), nl.
  4801. ppx([],_).
  4802. ppx([H|T],I)  :-  pp(H,I),ppx(T,I).
  4803.  
  4804.  
  4805. a(newcastle,carlisle,58).
  4806. a(carlisle,penrith,23).
  4807. a(townB,townA,15).
  4808. a(penrith,darlington,52).
  4809. a(townB,townC,10).
  4810. a(workington, carlisle,33).
  4811. a(workington,townC,5).
  4812. a(workington, penrith,39).
  4813. a(darlington,townA,25).
  4814.  
  4815. legalnode(X,Trail,Y,Dist,NewDist) :- 
  4816.     (a(X,Y,Z1) ; a(Y,X,Z1)),
  4817.     not(mem(Y,Trail)),
  4818.     NewDist is Dist + Z1.
  4819.  
  4820. go(Start,End,Travel) :-
  4821.       go3([r(0,[Start])],End,R55),
  4822.       rev(R55,Travel).
  4823.  
  4824. findall(X5,G,_) :-
  4825.       asserta(found(mark)),
  4826.       G,
  4827.       asserta(found(X5)),
  4828.       fail.
  4829. findall(_,_,L5)  :-  collect_found([],M5),!, L5  =  M5.
  4830.  
  4831. collect_found(S,L5)  :-  getnext(X5), !, collect_found([X5|S],L5).
  4832. collect_found(L5,L5).
  4833.  
  4834. getnext(X5)  :-  retract(found(X5)), !, X5 \== mark.
  4835.  
  4836. go3(Rts,Dest,Route) :- 
  4837. shortest(Rts,Shortest,RestRts),
  4838. proceed(Shortest,Dest,RestRts,Route).
  4839.  
  4840.  
  4841. proceed(r(Dist,Route),Dest,_ ,Route) :- Route = [Dest|_].
  4842.  
  4843.  
  4844. proceed(r(Dist,[Last|Trail]),Dest,Rts,Route)  :- 
  4845. findall(r(D1,[Z1,Last|Trail]),
  4846. legalnode(Last,Trail,Z1,Dist,D1),List),
  4847. append(List,Rts,NewRts),go3(NewRts,Dest,Route).
  4848.  
  4849.  
  4850. shortest([Route|Rts],Shortest,[Route|Rest])  :- 
  4851. shortest(Rts,Shortest,Rest),shorter(Shortest,Route),!.
  4852. shortest([Route|Rest],Route,Rest).
  4853. shorter(r(M1,_),r(M2,_)) :- M1 < M2.
  4854.  
  4855. look :- print('enter the starting location: '),nl,
  4856.          ratom(Beg),nl,
  4857.     print('enter the destination: '),
  4858.     nl,ratom(Dest),
  4859.     go(Beg,Dest,RRT),
  4860.     pp( RRT, 1 ).
  4861.  
  4862. 11-22-85
  4863.  
  4864.  
  4865. Dear Bob,
  4866.  
  4867.      I received your letter and the disk with EDPROLOG today and
  4868. must admit I was very gratified to find you were interested in my
  4869. Tree puzzle program - and thank you for the new ProLog!
  4870.  
  4871.      I have been happily busy with logic problems and syllogisms since
  4872. doing the Tree puzzle and I include two other of my efforts on this disk.
  4873. All three programs work just fine on my AT&T 6300 and all three have
  4874. simple start-up commands (like "go." or "hello.").  My machine does have
  4875. quite a lot of RAM (640k) but, as I understand things, this should not
  4876. pose problems for users with smaller systems since the language only
  4877. makes use of about 256k.  I hope this is the case.
  4878.  
  4879.      You will be interested to know that I have started planning a 
  4880. "free university" style course for next semester at the community college
  4881. where I teach.  The course, Introduction to ProLog, will be using your
  4882. public domain version of the language and Clocksin & Mellish's book.
  4883. This first offering will probably be limited to other staff members,
  4884. but if all goes well I'll offer it next year to faculty & students.  My
  4885. real motive is to enable my own learning as much as to teach the language.
  4886.  
  4887.      Hope you enjoy the programs.  They really were a lot of fun to write.
  4888.  
  4889.  
  4890.  
  4891.  
  4892. Sincerely,
  4893.  
  4894.  
  4895.  
  4896.  
  4897. Tom Sullivan
  4898. 5415 Grand Ave.
  4899. Western Springs, IL 60558
  4900. /* A Prolog solution to Family Trees by Virginia McCarthy.
  4901.             Tom Sullivan
  4902.             5415 Grand Ave.
  4903.             Western Springs, IL 60558  -  October 30,1985.
  4904. */
  4905.  
  4906. northside (larch).
  4907. northside (catalpa)    :- northside ('Grandes').
  4908. northside ('Grandes')  :- have ('Grandes', larch).
  4909. have ('Grandes',larch) :- not_own ('Crewes',larch),
  4910.                           not_own ('Dews',larch),
  4911.                           not_own ('Lands',larch).
  4912.  
  4913. southside ('Crewes').
  4914. southside ('Dews').
  4915. southside (dogwood) :- northside (larch), northside (catalpa).
  4916. southside (ginko)   :- northside (larch), northside (catalpa).
  4917.  
  4918. here ('Grandes').
  4919. there (catalpa).
  4920.  
  4921. /* belongs_to provides a recursive definition of membership in a list
  4922.    see Clocksin & Mellish p. 53.  */
  4923.  
  4924. belongs_to (X,[X|_]).
  4925. belongs_to (X,[Y|Z]) :- belongs_to (X,Z).
  4926.  
  4927. same_first_letter (['Dews', dogwood]).
  4928. same_first_letter (['Grandes',ginko]).
  4929. same_first_letter (['Lands',larch]).
  4930. same_first_letter (['Crewes',catalpa]).
  4931.  
  4932. human (['Grandes','Crewes','Dews','Lands']).
  4933. plant ([catalpa,ginko,dogwood,larch]).
  4934.  
  4935. person (X) :- human (Y), belongs_to (X,Y).
  4936. tree (X)   :- plant (Y), belongs_to (X,Y).
  4937.  
  4938. not_own (X,Y) :- same_first_letter (Z),
  4939.                  belongs_to (X,Z), belongs_to (Y,Z).
  4940. not_own (X,Y) :- here (X), there (Y).
  4941. not_own (X,Y) :- (person (X), person (Y));
  4942.                  (tree (X), tree (Y)).
  4943. not_own (X,Y) :- (northside (X),southside (Y));
  4944.                  (southside (X),northside (Y)).
  4945. not_own ('Crewes', X) :- owns ('Dews', X).
  4946. not_own ('Lands', X)  :- owns ('Crewes', X).
  4947. not_own ('Lands', X)  :- owns ('Dews',X).
  4948.  
  4949.  
  4950. owns (X,Y) :- person (X), tree (Y), not (not_own (X,Y)).
  4951. hello :- owns(Person,Tree),print (Person,' owns the ',Tree).
  4952.  
  4953. /* query with "owns (Person,Tree), write (Person,Tree)."
  4954.    or just say "hello."  */
  4955.  
  4956.  
  4957. /* The puzzle - "Family Trees" by Virginia McCarthy as found in
  4958.    Dell Champion Variety Puzzles, November, 1985
  4959.  
  4960.    The Crewes, Dews, Grandes, and Lands of Bower Street each have 
  4961.    a front-yard tree -- a catalpa, dogwood, gingko, and larch.  The
  4962.    Grandes' tree and the catalpa are on the same side of the street.
  4963.    The Crewes live across the street from the larch, which is across
  4964.    the street from the Dews' house.  If no tree starts with the same 
  4965.    letter as its owner's name, who owns which tree?     
  4966. */
  4967. /* A deduction problem from Dell Official Puzzles December, 1985.
  4968.    ProLog program by Tom Sullivan  -  November, 1985
  4969.  
  4970.    Abby, Barb, & Cora have clothes in  blue, green, purple, red & yellow.
  4971.    None wears yellow with red.  Each has a two-piece outfit in two colors.
  4972.    Abby is wearing blue.  Barb is wearing yellow but not green.  Cora wears
  4973.    green but not blue or purple.  One has on red.  One color is worn by both
  4974.    Barb and Cora, while Abby & Barb, between them, have on four different
  4975.    colors.  Name the colors each woman is wearing.
  4976. */
  4977.  
  4978. human ([abby,barb,cora]).
  4979. hue ([blue,green,purple,red,yellow]).
  4980.  
  4981. member (X,[X|_]).
  4982. member (X,[_|Y]) :- member (X,Y).
  4983.  
  4984. person (X) :- human (Y), member (X,Y).
  4985. color (X) :- hue (Y), member (X,Y).
  4986.  
  4987. hason (abby,blue).
  4988. hason (barb,yellow).
  4989. hason (cora,green).
  4990.  
  4991. notwear (barb,green).
  4992. notwear (cora,blue).
  4993. notwear (cora,purple).
  4994. notwear (X,Y) :- not (X = cora),hason (Z,Y).
  4995. notwear (abby,X) :- wears (barb,Z),member (X,Z).
  4996. notwear (cora,X) :- wears (abby,Z),member (X,Z).
  4997.  
  4998. wears (X,([Color1,Color2])) :- person (X), color (Color1), color (Color2),
  4999.                                hason (X,Color1),
  5000.                                not (notwear (X,Color2)),
  5001.                                not (Color1 = Color2),
  5002.                                not ((Color1 = red),(Color2 =yellow);
  5003.                                 (Color1 = yellow), (Color2 = red)).
  5004.  
  5005. go :- wears (X,Y),print (X,' wears ',Y).
  5006.  
  5007. /* to query type >> go.<CR>  */
  5008.  
  5009.  
  5010.  
  5011.  
  5012. /* A ProLog program to handle syllogisms of the type
  5013.                        All X are Y
  5014.                        Z is X
  5015.           Therefore -  Z is Y
  5016.  
  5017.    Tom Sullivan - 5415 Grand Ave. Western Springs, IL 60558
  5018.                      November, 1985
  5019.    Type go.<CR> to run the program.  Enjoy.
  5020. */
  5021.  
  5022. go :- nl,nl,nl,nl,nl,nl,nl,nl,nl,
  5023.       nl,nl,nl,nl,nl,nl,nl,nl,nl,
  5024.       print ('                     <<<<<   Theorem Prover   >>>>>'),
  5025.       nl,nl,
  5026.       print ('         Enter the name of a Greek,animal,plant,fish,insect,or bird.'),
  5027.       go1.
  5028.  
  5029. go1 :- nl,nl,nl,nl,nl,print ('Name  >> '),
  5030.        read (N),
  5031.        onlist (N),!.  /* see Clocksin & Mellish pp. 88-90  for use of cut */
  5032.  
  5033. listof (men,    ([socrates,plato,aristotle,homer])).
  5034. listof (animals,([dog,cat,horse,cow,pig,bear,lion])).
  5035. listof (plants, ([rose,petunia,daisy,oak,elm,corn])).
  5036. listof (fish,   ([waleye,pike,muski,bass,trout])).
  5037. listof (insects,([ant,beetle,spider,fly,mantis])).
  5038. listof (birds,  ([wren,robin,heron,eagle,hawk,crow])).
  5039.  
  5040. mortals ([men,animals,plants,fish,insects,birds]).
  5041.  
  5042. member (X,[X|_]).
  5043. member (X,[_|Y]) :- member (X,Y).      /* see C&M p.53  */
  5044.  
  5045. onlist (N) :- listof (Y,(Z)), member (N,Z),
  5046.               nl,nl,print ('Searching ... ',Y),
  5047.               nl,nl,print ('        1. ',N,' is in ',Y,'  ... and '),
  5048.               mortal (Y,N);stop.
  5049.  
  5050. mortal (Y,N) :- mortals (Z), member (Y,Z),
  5051.                 nl,nl,print ('Searching .... mortals'),
  5052.                 nl,nl,print ('        2. ',Y,' are mortal.'),
  5053.                 nl,nl,print ('        Therefore ',N,' is mortal.'), go1.
  5054.  
  5055. stop :- nl,print ('   That\'s not in the data!'),
  5056.         nl,nl,print ('                           Type <go.> for more.').
  5057. /* 
  5058. Except for the PD version, A.D.A. supports the grammar rule syntax. 
  5059. If the syntax is supported, one could ask the question:
  5060. sentence( X, [every, man, loves, a, woman], [] ).
  5061. and see the result translated into a formula of the predicate calculus.
  5062. If you want to compile this under the PD version, add the declaration:
  5063.   op( 150, xfy, '-->' ). However, the program won't run under type PD
  5064. unless you write a grammar rule expander (definitely feasible). 
  5065. */
  5066.  
  5067.  
  5068. ?-op( 100, xfx, '$' ).
  5069. ?-op( 150, xfy, '->' ).
  5070.  
  5071. sentence( P ) --> noun_phrase(X,P1,P), verb_phrase(X,P1).
  5072.  
  5073. noun_phrase(X, P1, P ) -->
  5074.    determiner(X,P2,P1,P), noun( X, P3 ),
  5075.    rel_clause( X, P3, P2 ).
  5076. noun_phrase( X, P, P ) --> proper_noun( X ).
  5077.  
  5078. verb_phrase( X, P ) --> trans_verb(X,Y, P1), noun_phrase(Y, P1, P ).
  5079. verb_phrase( X, P ) --> intrans_verb(X, P ).
  5080.  
  5081. rel_clause(X,P1,(P1$P2)) --> [that], verb_phrase(X, P2).
  5082. rel_clause(_, P, P) --> [].
  5083.  
  5084. determiner(X, P1, P2, all(X, (P1->P2))) --> [every].
  5085. determiner(X, P1, P2, exists(X,(P1$P2))) --> [a].
  5086.  
  5087. noun(X, man(X) ) --> [man].
  5088. noun(X, woman(X)) --> [woman].
  5089.  
  5090. proper_noun(john) --> [john].
  5091.  
  5092. trans_verb(X, Y, loves(X,Y)) --> [loves].
  5093.  
  5094. intrans_verb(X, lives(X) ) --> [lives].
  5095. /*   PIE.TM : A PROLOG INFERENCE ENGINE AND TRUTH MAINTENANCE      */
  5096. /*            SYSTEM                                               */
  5097.  
  5098.  
  5099.  
  5100. /* This file contains most of the fundamental predicates necessary */
  5101. /* for doing truth maintenance. PIE uses the prolog interpreter as */
  5102. /* an input parser by declaring most of the PIE syntax as goals.   */
  5103. /* Prior to execution the operators must be declared.This is       */
  5104. /* simplified by using the redirect feature of ADA Prolog with the */
  5105. /* command line:       'prolog kops'                               */
  5106. /* The system is not yet complete and several extentions are       */
  5107. /* planned, many of which have already been implemented but        */
  5108. /* remain to be integrated with this particular piece of code.     */
  5109. /* Examples of planned extentions follow: one-directional rules,   */
  5110. /* a non-rule based inference based on mathematical set covering,  */
  5111. /* confidence factors, and more refined techniques for displaying  */
  5112. /* and editing a knowledge base. At the moment it is useful to know*/
  5113. /* or have a copy of the underlying representation. There is not   */
  5114. /* a lot of code here and it has not been thoroughly tested, but it*/
  5115. /* is quite powerful and flexible.                                 */
  5116.  
  5117.  
  5118. /* Sets 'X implies Y' up as a goal. NOTE: In order for the input to*/
  5119. /* be parsed properly antecedents and consequents must be given as */
  5120. /* lists, e.g. '[X is a male,X is a human] implies [X is a man]'.  */
  5121. /* Consequents may themselves be rule declarations. The rules      */
  5122. /* are bi-directional and may contain Prolog goals as elements     */
  5123. /* of the antecedent or consequent lists. To force forward         */
  5124. /* chaining 'fc' may be made a member of the antecedent or         */
  5125. /* consequent lists.                                               */
  5126.  
  5127. X implies Y :-
  5128.         assert_r(X implies Y).
  5129.  
  5130.  
  5131.  
  5132. /* Cycles through all the forward chaining rules to find out if  */
  5133. /* the most recent assertion will cause any to fire. The         */
  5134. /* efficiency of this function can be increased dramatically by  */
  5135. /* copying the original rule to a 'non-conflict' stack and       */
  5136. /* effacing those conditions that have already been met. This    */
  5137. /* will result in ever shorter antecednt lists for the rules.    */
  5138.  
  5139.  
  5140. fc:-
  5141.         clause(rule(N,D,Y implies Z,C),true),
  5142.         given_mem(Y),
  5143.         check_mult_con(N,Z),
  5144.         fail.
  5145. fc.
  5146.  
  5147. /* Checks to see if an antecedent that is part of a list exists  */
  5148. /* as a given in the kb.                                         */
  5149.  
  5150. given_mem([]).
  5151. given_mem([Y|Z]):-
  5152.         (Y;fact(N,D,Y,C)),
  5153.         given_mem(Z),!.
  5154.  
  5155. /* Reads through a list of consequents and passes them on to     */
  5156. /* the infer function only if they do not already exist in the   */
  5157. /* kb. This should be enhanced so that confidence factors can    */
  5158. /* be incremented.                                               */
  5159.  
  5160. check_mult_con(N,[]).
  5161. check_mult_con(N,[X|Y]):-
  5162.         infer(N,X),
  5163.         check_mult_con(N,Y),!.
  5164.  
  5165.  
  5166.  
  5167. /*The PIE assert adds facts to the knowledge base. While doing  */
  5168. /*so it checks to make sure that no conflicting facts exist. If */
  5169. /*conflicting facts do exist their identity is displayed.       */
  5170. /*Planned extentions include backward truth maintenance, wherein */
  5171. /*the inferences that led to both of the conflicting facts will */
  5172. /*be evaluated for confidence and 'distance' from input.        */
  5173. /* A typical assertion made by the user might look like:        */
  5174. /*                assert([bill is a man]).                      */
  5175. /* If the assert(X) is followed by an 'fc', forward chaining    */
  5176. /* will occur for the entire system.                            */
  5177.  
  5178. /* This is a special instance of the PIE assert. It allows new  */
  5179. /* relations to be declared in the form of operators. Asserting */
  5180. /* 'loves is a relation' will allow subsequent use of 'loves' as*/
  5181. /* an infix operator in antecedents or consequents of rules,    */
  5182. /* e.g. [X loves Y] implies [Y loves X].                        */
  5183.  
  5184. assert([]).
  5185. assert([X is a Rel|Y]) :-
  5186.         nonvar(R),
  5187.         R=relation,
  5188.         gensym(rel,N),
  5189.         asserta(relation(N,_)),
  5190.         op(10,xfx,X),
  5191.         assert(Y).
  5192. assert([X|Y]):-
  5193.         fact(Number,Dependence,X,Confidence),
  5194.         assert(Y).
  5195. assert([X|Y]):-
  5196.         fact(Number,Dependence,not(X),Confidence),!,
  5197.         print('Sorry, in conflict with existing information.'),nl,
  5198.         print('Dependency for ',Number),nl,
  5199.         prt_dependency(Number),
  5200.         assert(Y).
  5201. assert([not(X)|Y]):-
  5202.         fact(Number,Dependence,X,Confidence),!,
  5203.         print('Sorry, in conflict with existing information.'),nl,
  5204.         print('Dependency for ',Number),nl,
  5205.         prt_dependency(Number),
  5206.         assert(Y).
  5207.  
  5208. assert([not(X)|Y]):-
  5209.         check_word(X,_),
  5210.         functor(X,F,N),
  5211.         (atom(X);N>0),
  5212.         gensym(f,Number),
  5213.         assertz(fact(Number,input,not(X),Conf)),
  5214.         print('Inserted: ',Number,' not',X),nl,!,
  5215.         assert(Y).
  5216. assert([X|Y]):-
  5217.         check_word(X,_),
  5218.         functor(X,F,N),!,
  5219.         N>0,
  5220.         gensym(f,Number),
  5221.         assertz(fact(Number,input,X,C)),
  5222.         print('Inserted: ',Number,' ',X),nl,!,
  5223.         assert(Y).
  5224.  
  5225.  
  5226. /* Specifically designed for adding rules to the knowledge base */
  5227.  
  5228. assert_r(not(X)):-
  5229.         check_word(X,Y),
  5230.         functor(X,F,N),
  5231.         F=implies,
  5232.         gensym(r,Number),
  5233.         assertz(rule(Number,input,not(X),Conf)),!,
  5234.         print('Inserted: ',Number,' not',X),nl.
  5235. assert_r(X):-
  5236.         check_word(X,Y),
  5237.         functor(X,implies,N),
  5238.         gensym(r,Number),
  5239.         assertz(rule(Number,input,X,Conf)),!,
  5240.         print('Inserted: ',Number,' ',X),nl.
  5241.  
  5242. /* The 'infer' clause allows assertions to be made as a result of */
  5243. /* inference. It is similar to 'assert', but allows the passing   */
  5244. /* of a dependency bound to 'N'.                                  */
  5245.  
  5246. infer(N,not(X)):-
  5247.         fact(Num,Dependence,X,Confidence),!,
  5248.         print('Sorry, in conflict with existing information.'),nl,
  5249.         print('Dependency of existing info ',Num,' ',X),nl,
  5250.         prt_dependency(Num),
  5251.         print('Dependence of new conflicting info not',X),nl,
  5252.         prt_dependency(N).
  5253. infer(N,X):-
  5254.         fact(Num,Dependence,not(X),Confidence),!,
  5255.         print('Sorry, in conflict with existing information.'),nl,
  5256.         print('Dependency of existing info ',Num,'not',X),nl,
  5257.         prt_dependency(Num),
  5258.         print('Dependence of new conflicting info ',X),nl,
  5259.         prt_dependency(N).
  5260. infer(N,X):-
  5261.         (X;fact(_,_,X,_);rule(_,_,X,_)).
  5262. infer(N,X):-
  5263.         X='implies'(_,_),
  5264.         gensym(r,Number),
  5265.         assertz(rule(Number,N,X,Conf)),
  5266.         print('Inserted: ',Number,' ',X),nl,!.
  5267. infer(N,X):-
  5268.         (atom(X);true),
  5269.         gensym(f,Number),
  5270.         assertz(fact(Number,N,X,Conf)),
  5271.         print('Inserted: ',Number,' ',X),nl,!.
  5272.  
  5273. /* Builds a vocabulary for the system and ensures that typographical errors */
  5274. /* are not introduced. A typographical error might result in what would     */
  5275. /* to be two different values for an attribute or two different attributes  */
  5276. /* for an object.                                                           */
  5277.  
  5278. check_word(X,_):-
  5279.         var(X).
  5280. check_word(X,_):-
  5281.         word(X).
  5282. check_word(X,Y):-
  5283.         X= '`s'(A,B),
  5284.         check_word(A,A1),
  5285.         check_word(B,B1).
  5286. check_word(X,Y):-
  5287.         X= 'is a'(A,B),
  5288.         check_word(A,A1),
  5289.         check_word(B,B1),
  5290.         setval(B1,A1).
  5291. check_word(X,Y):-
  5292.         X=F(A,B),
  5293.         check_word(A,A1),
  5294.         check_word(B,B1),
  5295.         setval(A1,B1).
  5296. check_word([X|Tail],_):-    /* Allows the use of ';'and lists within a list */
  5297.         check_word(X,_),
  5298.         (Tail =[];check_word(Tail,_)).
  5299. check_word(X,Y):-
  5300.         print('Is ',X,' a correct value? y/n: '),
  5301.         ((ratom(y),X=Y);(replace_value(Y))).
  5302. replace_value(Y):-
  5303.         print('Please, type in correct value: '),
  5304.         ratom(Y).
  5305. setval(A,B):-
  5306.         nonvar(A),
  5307.         nonvar(B),
  5308.         asserta(legval(A,B)).
  5309. setval(A,B):-
  5310.         nonvar(A),
  5311.         asserta(word(A)),
  5312.         fail.
  5313. setval(A,B):-
  5314.         nonvar(B),
  5315.         asserta(word(B)),
  5316.         fail.
  5317. setval(_,_).
  5318.  
  5319. /* A simple recursive function that will print out the rule    */
  5320. /* numbers on which a fact or rule depends. Extensions to this */
  5321. /* will allow for viewing in various modes and editing.        */
  5322.  
  5323. prt_dependency(input).
  5324. prt_dependency(N):-
  5325.         (fact(N,input,_,_);rule(N,input,_,_)),
  5326.         print('input').
  5327. prt_dependency(N):-
  5328.         (fact(N,D,_,_);rule(N,D,_,_)),
  5329.         (fact(D,D1,X,Conf);rule(D,D1,X,Conf)),
  5330.         write(D),tab(2),write(X),tab(2),write(Conf),nl,
  5331.         prt_dependency(D1).
  5332.  
  5333. rule(X):-
  5334.     rule(X,Dep,Body,Conf),
  5335.     print(X,'  ',Dep,'  ',Body,'  ',Conf),nl.
  5336. rules:-
  5337.     clause(rule(A,B,C,D),true),
  5338.     print(A,' ',B,' ',C,' ',D),nl,
  5339.     fail.
  5340. rules.
  5341.  
  5342. fact(X):-
  5343.     fact(X,Dep,Body,Conf),
  5344.     print(X,'  ',Dep,'  ',Body,'  ',Conf),nl.
  5345. facts:-
  5346.     clause(fact(Num,Dep,Body,Conf),true),
  5347.     print(Num,'  ',Dep,'  ',Body,'  ',Conf),nl,
  5348.     fail.
  5349. facts.
  5350.  
  5351.  
  5352.  
  5353. /* Allows removal of rules or facts by reference to their gensym  */
  5354. /* index. This could easily be enhanced by allowing instantiation */
  5355. /* through explicitly typing out the item to be removed.          */
  5356. /* Automatically removes assertions that depend on the retracted  */
  5357. /* item.                                                          */
  5358.  
  5359. remove(N):-
  5360.         retract(rule(N,D,X implies Y,C)),
  5361.         print('Removed: ',N,' ',X,'implies',Y),nl,
  5362.         remove_con(N,Y).
  5363. remove(N):-
  5364.         retract(fact(N,D,X,C)),
  5365.         clause(rule(N1,_,Y implies Z,_),true),
  5366.         print('Removed: ',N,' ',X),nl,
  5367.         mem(X,Y),
  5368.         remove_con(N1,Z),
  5369.         fail.
  5370.  
  5371. /* 'Remove' will automatically forward chain in order re-infer  */
  5372. /* things that may be obtained through a different route than   */
  5373. /* that affected by the retraction process. This is necessary   */
  5374. /* because not all facts are taken advantage of in inferencing. */
  5375. /* That is to say, if a fact already exists 'infer' and 'assert'*/
  5376. /* will not add them redundantly to the kb. This will change    */
  5377. /* with the addition of confidence factors.                     */
  5378.  
  5379. remove(N):-
  5380.         fc.
  5381.  
  5382.  
  5383. /* Exhaustively checks facts in the kb and removes them if they */
  5384. /* depend on another item removed. NOTE: 'N=D' is part of a     */
  5385. /* disjunction, if it fails the fact will be reinserted in the  */
  5386. /* kb. At the moment this does not take advantage of the ADA    */
  5387. /* Prolog indexing capability, but it should in a dedicated     */
  5388. /* ADA application.                                             */
  5389.  
  5390. remove_con(N,[]).
  5391. remove_con(N,[X|Y]):-
  5392.         retract(fact(N1,N,X,C)),
  5393.         print('Removed: ',N1,' ',X),nl,
  5394.         remove_con(Y).
  5395. remove_con([X|Y]):-
  5396.         remove_con(Y).
  5397.  
  5398.  
  5399.  
  5400.  
  5401. /* Activates backward chaining. A complex function, the first */
  5402. /* two clauses REQUIRE a list to function properly, but valid- */
  5403. /* ation is not done. This is required by the inference       */
  5404. /* mechanism. Its effect is to ensure that inheritance is not */
  5405. /* carried over to uninstantiated objects.                    */
  5406.  
  5407. obtain([]).
  5408. obtain(X):-
  5409.         X =[Y|Z],!,
  5410.         obtain_1(Y),
  5411.         obtain(Z).
  5412. obtain_1(X):-
  5413.         X.
  5414. obtain_1(X):-
  5415.         clause(fact(N,D,X,C),true).
  5416.  
  5417. obtain_1(X):-
  5418.         clause(rule(N,D,Y implies Z,C),true),
  5419.         nl,
  5420.         not(chk(N)),     /* Prevents double pattern match. */
  5421.         mem(X,Z),
  5422.         asserta(chk(N)),
  5423.         obtain(Y).      /* Recursive check for ant as a con.*/
  5424. obtain_1(F(A,B)):-
  5425.         X=F(A,F1(C,D)),
  5426.         nonvar(F1),!,
  5427.         print(A,' ',F,' ',C,' ',F1,' ',D),nl,
  5428.         obtain_1a(F(A,F1(C,D))),
  5429.         assert([F(A,F1(C,D))]),
  5430.         refresh.          /* Removes 'chk' tag. */
  5431. obtain_1(F(A,B)):-
  5432.         print(A,' ',F,' ',B),nl,
  5433.         obtain_1b(F(A,B)),
  5434.         assert([F(A,B)]),
  5435.         refresh.
  5436. obtain_1a(F(A,F1(B,C))):-
  5437.         print('Please,fill in the blanks:'),nl,
  5438.         get_val(A,_),
  5439.         print(A,' ',F,' '),
  5440.         get_val(B,A),
  5441.         print(B,' ',F1,' '),
  5442.         get_val(C,B).
  5443. obtain_1b(F(A,B)):-
  5444.         print('Please,fill in the blanks:'),nl,
  5445.         get_val(A,_),
  5446.         print(A,' ',F,' '),
  5447.         get_val(B,A).
  5448. get_val(X,_):-
  5449.         nonvar(X).
  5450. get_val(X,Y):-
  5451.         listvals(Y),
  5452.         r_val(X,Y).
  5453. r_val(X,Y):-
  5454.         ratom(Z),
  5455.       /*  legval(Y,Z), */
  5456.         Z=X.
  5457.  
  5458.  
  5459. /* Refreshes rules */
  5460. refresh:-
  5461.     retract(chk(_)),
  5462.     fail.
  5463. refresh.
  5464.  
  5465.  
  5466. listvals(_).  /* Temporarily axiomatic */
  5467. listvals(X):-
  5468.         clause(legval(X,Y),true),
  5469.         print(Y),nl,
  5470.         fail.
  5471. listvals(_).
  5472.  
  5473.  
  5474. /* Standard Prolog append.                                      */
  5475.  
  5476. append([],X,X).
  5477. append([A|B],C,[A|D]):-
  5478.         append(B,C,D).
  5479.  
  5480.  
  5481. /* Standard Prolog member.                                      */
  5482.  
  5483. mem(X,[X|_]).
  5484. mem(X,[Y|Z]):-
  5485.         mem(X,Z).
  5486.  
  5487. /* Standard Prolog gensym.                                       */
  5488.  
  5489. gensym( Root, Atom ) :-
  5490.         get_num( Root, Num ),
  5491.         name( Root, Name1 ),
  5492.         integer_name( Num, Name2 ),
  5493.         append( Name1, Name2, Name ),
  5494.         name( Atom, Name ).
  5495.  
  5496. get_num( Root, Num ) :-
  5497.         retract( current_num( Root, Num1 )), !,
  5498.         Num is Num1 + 1,
  5499.         asserta( current_num( Root, Num)).
  5500.  
  5501. get_num( Root, 1 ) :- asserta( current_num( Root, 1 )).
  5502.  
  5503. integer_name( Int, List ) :- integer_name( Int, [], List ).
  5504. integer_name( I, Sofar, [C|Sofar] ) :-
  5505.         I < 10, !, C is I + 48.
  5506. integer_name( I, Sofar, List ) :-
  5507.         Tophalf is I/10,
  5508.         Bothalf is I mod 10,
  5509.         C is Bothalf + 48,
  5510.         integer_name( Tophalf, [C|Sofar], List ).
  5511.  
  5512.  
  5513. append( [], L, L ).
  5514. append( [Z|L1], L2, [Z|L3] ) :- append( L1, L2, L3 ).
  5515.  
  5516.  
  5517. prolog kops
  5518.  
  5519. batch.
  5520. op(240,xfx,'implies').
  5521. op(240,xfx,'only if').
  5522. op(220,xfx,'is a').
  5523. op(220,yfy,'`s').
  5524. op(219,xfx,'eq').
  5525. nl,
  5526. print('\n                                   PIE.TM\n',
  5527. '           A Forward and Backward Chaining Prolog Inference Engine\n',
  5528. '                          With Truth Maintenance\n',
  5529. '                Public Domain Version 1.1   19 November 1985\n',
  5530. '                            By Simon Blackwell\n',
  5531. '          Dept. of Philosophy, Bowling Green State University, Ohio').
  5532. consult('know.pro').
  5533. see(user).
  5534. ..head01rCS680
  5535. ..foot59ci
  5536.  
  5537.                   A Prolog Augmented Transition Network Parser
  5538.  
  5539.                                Table of Contents
  5540.  
  5541.  
  5542. 1.  General                                                         1
  5543.  
  5544. 2.  ATN Form                                                        1
  5545.  
  5546.         Figure 1.  ATN Network                                      1
  5547.         Figure 2.  Phrase Network                                   2
  5548.  
  5549. 3.  Approach                                                        2
  5550.                                                                        
  5551.         Phase I                                                     2
  5552.         Phase II                                                    2
  5553.         Phase III                                                   2
  5554.  
  5555. 4.  Phase I                                                         2
  5556.  
  5557. 5.  Phase II                                                        3
  5558.  
  5559. 6.  Phase III                                                       5
  5560.                                                                     
  5561.         ATNBLD                                                      6
  5562.         ATNNEW                                                      8
  5563.  
  5564. 7.  Conclusions                                                     9
  5565.  
  5566. Attachements:                                                       
  5567.  
  5568. 1.  ATN.PRO                                                         
  5569.  
  5570.         Program Listing                                             1-1
  5571.         Phase I - Example I                                         1-5
  5572.         Phase I - Example II                                        1-6
  5573.  
  5574. 2.  ATNREV.PRO                                                      
  5575.  
  5576.         Program Listing                                             2-1
  5577.         Phase II - Example I                                        2-4
  5578.         Phase II - Example II                                       2-4
  5579.  
  5580. 3.  ATNBLD.PRO                                                      
  5581.  
  5582.         Program Listing                                             3-1
  5583.         Example ATN Definition                                      3-3
  5584.  
  5585. 4.  ATNNEW1.PRO                                                     
  5586.  
  5587.         Program Listing                                             4-1
  5588.         Phase III - Example I                                       4-4
  5589.         Phase III - Example II (Subject Predicate Agreement)        4-5
  5590. ..head01rCS680
  5591. ..foot59c##
  5592.                   A PROLOG AUGMENTED TRANSITION NETWORK PARSER
  5593. 
  5594.                                   submitted by
  5595.  
  5596.                               Ludwig J. Schumacher
  5597.  
  5598.                                November 26, 1985
  5599.  
  5600.  
  5601. 1.  General.  This report documents the development of an Augmented Transition
  5602. Network (ATN) sentence parser in the PROLOG language and is submitted in partial
  5603. fulfillment of the requirements for CS 680, Natural Language Processing, George
  5604. Mason University, Fall 1985.  It is assumed that the reader is familiar with
  5605. natural language processing and PROLOG so associated terms will be used without
  5606. explanation.  The author had no prior experience with logic programming and does
  5607. not presume to evaluate the PROLOG language, only that small subset of commands
  5608. he was able to master in attempting to apply the language to this specific
  5609. project.  The examples contained herein are executed under A.D.A. PROLOG,
  5610. ver 1.6c, (c) Automata Design Associates 1985.
  5611.  
  5612.  
  5613. 2.  ATN Form.  The form of the ATN which is used in this paper is shown in
  5614. Figure 1.  This form has been chosen not as comprehensive coverage of English
  5615. sentence structure but to provide a simple form which does incorporate the major
  5616. features of ATNs.  Figure 2 is the noun and prepositional phrase network.
  5617. 
  5618.               -  Transition from node to node based upon specified conditions.
  5619.  
  5620.               -  Optional conditions, such as the determiner and adjective in
  5621.                  the noun phrase.
  5622.                  
  5623.               -  Augmentation with sub-networks such as the noun and
  5624.                  prepositional phrases.
  5625.  
  5626.               -  Recursiveness such as the adjective in the noun phrase and the
  5627.                  noun phrase at node 2.
  5628.  
  5629.  
  5630.  
  5631.  
  5632.                                         np              pp
  5633.                                       *   *           *   *
  5634.                             verb     \/  *      pp   \/ * 
  5635.       np  **** >  q1 ************** > q2/ ********** > q3/
  5636.       *              *                /\
  5637. q0 *                    *    aux      * verb
  5638.       *                     *         *
  5639.       aux **** >  q4 ************* >  q5
  5640.                           np
  5641. 
  5642.  
  5643.  
  5644.  
  5645.                              Figure 1.  ATN Network
  5646.                    adj
  5647.        det      *   *
  5648.       ******    \/  *     noun                         prep
  5649. qnp *       * >  qnp1 ********** > qnp2/        qpp ****** > qnp
  5650.       ******
  5651.        jump
  5652.  
  5653.                            Figure 2.  Phrase Network
  5654.  
  5655.  
  5656. 3.  Approach.  The project was conducted in three phases.
  5657.  
  5658.     a.  Phase I.  Phase I was experimentation with PROLOG to develop some
  5659. working application. An ATN parser was programmed but only by forcing PROLOG
  5660. into a procedural mold.  This phase culminated in a briefing presented in class
  5661. on 24 October.
  5662.  
  5663.     b.  Phase II.  Phase II was the translation of the procedures developed in
  5664. Phase I into facts and rules appropriate for a logic program, which would more
  5665. fully exploit the capabilities of PROLOG.
  5666.  
  5667.     c.  Phase III.  Phase III was additional experimentation to make the programs
  5668. more dynamic and to exploit the power of an ATN to pass differing information
  5669. depending upon the particular transition.  These experiments included procedures
  5670. to automatically update the vocabulary, allow for user defined networks,
  5671. refinement of the database search procedures, and incorporation of subject and
  5672. predicate agreement verification.
  5673.  
  5674.  
  5675. 4.  Phase I
  5676.  
  5677.     a.  The program developed during Phase I (Attachment 1) is not a logic
  5678. program, but a set of procedures executed with the PROLOG language.  Procedures
  5679. are defined as a set of 'q' rules which are passed the current node number and
  5680. the unparsed and parsed parts of the sentence.  Each set of procedures defined
  5681. the actions to be taken at that node. For example, q(0,_) are the procedures for
  5682. node 0, q(1,_,_) are the procedures for node 1, etc.
  5683.  
  5684.     b.  There are a number of limitations to this approach.
  5685.  
  5686.               -  The addition of a node requires a new set of procedures and
  5687. modification of the code for each node from which a transition can be made.
  5688.  
  5689.               -  It would be difficult to modify the code dynamically, since
  5690. procedures must be executed in sequence, and changes would have to be inserted at
  5691. specific points.
  5692. 
  5693.               -  Elimination of a node requires not only the elimination of the
  5694. procedure for that node, but the removal of all calls to that node from other
  5695. procedures.
  5696.  
  5697. ..page
  5698. 5.  Phase II.  Phase II was the development of a logic program to accomplish the
  5699. same functions as that developed during Phase I.  The approach was to translate
  5700. the statement, "There is a transition from node X to node Y on condition Z", to
  5701. the PROLOG equivalent "arc(X,Y,Z)".  The complete program is at Attachment 2 and
  5702. appropriate sections are reproduced below.
  5703. 
  5704.     a.  The first step was to redefine the facts.  The transitions are in the
  5705. form of arc(from node,to node,condition).
  5706.  
  5707.             arc(q0,q1,np).
  5708.             arc(q1,q2,verb).
  5709.             arc(q2,q2,np).
  5710.             arc(q2,q3,pp).
  5711.             arc(q0,q4,aux).
  5712.             arc(q4,q5,np).
  5713.             arc(q1,q5,aux).
  5714.             arc(q5,q2,verb).
  5715.  
  5716.  
  5717.     b. The terminal nodes are identified by term(at node,empty list), where the
  5718. remainder of the sentence is the second variable.
  5719.  
  5720.             term(q2,[]).
  5721.             term(q3,[]).
  5722.  
  5723.     c.  Since phrase transitions are based upon a series of words rather than a
  5724. single condition, they are treated as separate networks.  The empty list as the
  5725. transition condition is used to effect a jump.
  5726.  
  5727.             arc(qnp,qnp1,det).
  5728.             arc(qnp,qnp1,[]).
  5729.             arc(qnp1,qnp1,adj).
  5730.             arc(qnp1,qnp2,noun).
  5731.             arc(qpp,qnp,prep).
  5732.  
  5733.  
  5734.     d.  With these 'facts' established, one can now use the recursive and
  5735. backtracking nature of PROLOG to find a path from the initial point to a
  5736. terminal node.
  5737.  
  5738.               1)  A sentence is input as a PROLOG list enclosed in brackets and
  5739. with each word separated by a comma.  There is no punctuation at the end of the
  5740. sentence.  All words must be in lower case.
  5741.  
  5742.               2)  Once the sentence, S, has been input, control is passed to the
  5743. rule trans (transition).  The variables are: current node, next node, parsed
  5744. sentence, sentence remaining to be parsed, and sentence remaining to be parsed
  5745. after transition.
  5746.  
  5747.          trans(q0,Nq,Parse,S,S1)
  5748. 
  5749. ..page
  5750.               3)  If the current node (Lq) is a terminal node and the remainder
  5751. of the sentence (S1) is null, then the sentence has been parsed.
  5752.  
  5753. trans(Lq,_,Parse,S1,_) :- term(Lq,S1),nl,
  5754.                           print('Completed ',Lq),
  5755.                           nl,print(Parse).
  5756.  
  5757.  
  5758.               4)  If the next word (S0) is the type (Type) to effect a
  5759. transition, then trans is called recursively.  (Note: Nbr is a variable designed
  5760. to provide information on the singularity or plurality of the word.  It is not
  5761. used in this example.)
  5762.  
  5763. trans(Lq,Nq,Parse,[S0|S1],S1) :- word(S0,Type,Nbr),
  5764.                                  arc(Lq,Nq,Type),
  5765.                                  nl,
  5766.                             print('Transition ',Lq,' ',Nq,' ',S0, ' ',Type),
  5767.                                  append(Parse,[[Type],S0],P1),
  5768.                                  !,
  5769.                                  trans(Nq,Z,P1,S1,S2).
  5770.  
  5771.  
  5772.               5)  If the next word in the sentence does not establish the
  5773. criteria for a transition, check to determine if a phrase does. If so, the rest
  5774. of the sentence is checked for the proper phrase, either np or pp. This requires
  5775. the separate network check, ptrans, which allows parsing as the network is
  5776. transitioned, but will return unchanged if it fails.
  5777. 
  5778.  
  5779.  
  5780. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,np),
  5781.                              ptrans(qnp,Nq,Lq,S0,[np],Parse).
  5782.  
  5783.  
  5784. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,pp),
  5785.                              ptrans(qpp,Nq,Lq,S0,[pp],Parse).
  5786.  
  5787.  
  5788.               6)  If no word or phrase has been found to effect a
  5789. transition, the sentence will not parse.
  5790.  
  5791.  
  5792. trans(Lq,Nq,Parse,S0,S1) :- !,nl,
  5793.                             print('The sentence failed at ',Lq),
  5794.                             nl,print('Parsed ',Parse),
  5795.                             nl,print('Left ',S0).
  5796.  
  5797.  
  5798.               7)  The phrase transition network code is almost identical to the
  5799. primary code, except that it continues to call itself until such time as it
  5800. reaches qnp2, which is the terminal node, or fails at a node other than qnp2.
  5801. In the first case it will effect a transition to the next node (Nq) and call
  5802. trans with the new data.  In the second case, ptrans will fail and conditions
  5803. remain unchanged.
  5804. ptrans(Bq,Nq,Lq,[S0|S1],Pr,Parse) :- word(S0,Type,Nbr),
  5805.                                      arc(Bq,Zq,Type),
  5806.                                      append(Pr,[[Type],S0],P1),
  5807.                                      !,
  5808.                                      ptrans(Zq,Nq,Lq,S1,P1,Parse).
  5809.  
  5810. ptrans(qnp2,Nq,Lq,S0,Pr,Parse) :- nl,
  5811.                                   print('Transition ',Lq,' ',Nq),
  5812.                                   nl,
  5813.                                   print(Pr),
  5814.                                   append(Parse,Pr,P1),
  5815.                                   !,
  5816.                                   trans(Nq,Rq,P1,S0,S1).
  5817.  
  5818.  
  5819. 6.  Phase III
  5820. 
  5821.     a.  These programs demonstrate that PROLOG can be used to develop an ATN
  5822. parser but still do not exploit the power of PROLOG to operate in a dynamic
  5823. environment.  Specific capabilities which should be included are:
  5824.  
  5825.               1)  The ATN should be able to provide additional information
  5826. beyond whether or not the sentence parsed.
  5827.  
  5828.               2)  The program should assist the user in construction of the ATN
  5829. definition.
  5830.  
  5831.               3)  The program should verify the words are in the vocabulary set
  5832. before attempting to parse, and if not, allow them to be added.
  5833.  
  5834.               4)  The database search should be efficient. Especially in the
  5835. case of a large vocabulary set, the initial form of word(Name,[type]) is
  5836. unacceptable in that PROLOG must conduct a linear search of the entire set of
  5837. words to identify success or failure.
  5838.  
  5839.                         (a)  Dr. Berghel, University of Nebraska, suggested in
  5840. his presentation at George Mason that the vocabulary be stored as individual
  5841. letters and the search space would be reduced to words of a particular length.
  5842. For example, the word 'the' would be in the database as "word(t,h,e)".  In order
  5843. to identify if "the" is in the vocabulary set, it is partitioned into the
  5844. individual letters and only those words with arity 3 would need to be searched.
  5845.  
  5846.                         (b)  An alternative to the use of arity would be to
  5847. construct each word as a separate fact.  Thus "the" would be represented as
  5848. "the(word)".  It is assumed that PROLOG is more efficient searching a database
  5849. of unique facts rather than one of fewer facts differentiated by arity.  There
  5850. may, however, be some impact on memory requirements.  It must also be noted that
  5851. this would not serve the spelling correction procedure outlined by Dr. Berghel.
  5852.  
  5853.                         (c)  A concept which could be integrated with either of
  5854. the two approaches outlined above would be to allow the facts which are used
  5855. more often to migrate to the front of the list. Specifically, exploit PROLOG's
  5856. capability to alter the program by deleting facts when used and adding them to
  5857. the front of the list.
  5858.     b.  The two programs at Attachments 3 and 4 incorporate some of these
  5859. concepts.  Attachment 3 is a listing and example use of the program 'ATNBLD'
  5860. which can be used to build the primary transition network.  Attachment 4,
  5861. 'ATNNEW', uses the network developed by ATNBLD, stores each word as a separate,
  5862. unique fact, and identifies sentences in which the subject and predicate are not
  5863. in number agreement.
  5864.  
  5865.               1) ATNBLD  ATNBLD requests the names of the nodes and the
  5866. conditions for transition and establishes a separate database for the network
  5867. defined by the user.  The initial node must be entered and all terminal nodes
  5868. identified.  Then the user defines paths to each terminal node.
  5869.  
  5870.                         (a)  BUILD.  Build is the entry point into the program.
  5871. It requests the start node (Q0), the terminal nodes, termnode, then transfers to
  5872. flow.  The predicate 'ret', defined in a standard routine, is used to retract
  5873. predicates.  It is used here to retract any predicates which would interfere
  5874. with the construction of the network.  The predicates generated within the
  5875. program are:
  5876.  
  5877.                         - term: defines that a node is a
  5878.                                 terminal node
  5879.  
  5880.                         - qend: identifies nodes that have a
  5881.                                 path to a terminal node
  5882.  
  5883.                         - arc:  identifies the transitions from
  5884.                                 node to node
  5885.  
  5886.  
  5887. build :- batch,ret(qend),nl,ret(arc),nl,ret(term),asserta(term([],[])),
  5888.          consult(node),nl,print('Enter the start node: '),read(Q0),
  5889.          asserta(qend(Q0)),termnode,flow(Q0).
  5890.  
  5891.  
  5892. termnode :- print('Enter the next terminal node or the word done: '),
  5893.             read(QT),
  5894.             not(QT=done),
  5895.             termck(QT),
  5896.             assertfa(node,term(QT,[])),
  5897.             asserta(qend(QT)),
  5898.             termnode.
  5899.  
  5900. termnode  :-  !,true.
  5901.  
  5902.  
  5903. termck(Qt)  :-  not(term(Qt,[]));
  5904.                 nl,print('Terminal node ',Qt,' already entered'),nl.
  5905.  
  5906. ..page
  5907.                         (b)  FLOW.  Flow is the primary control structure.  It
  5908. requests the next node and the condition for transition.  It verifies that the
  5909. condition is valid, that the arc has not been previously defined, and adds it to
  5910. the database. The predicate 'qendck' verifies a path has been completed.
  5911.  
  5912. flow(Q0)  :- nl,print('Transition from ',Q0,' to ? '),read(Qnext),
  5913.              print(' on condition ? '),read(Con),
  5914.              con(Q0,Con),arcck(Q0,Qnext,Con),
  5915.              assertfz(node,arc(Q0,Qnext,Con)),
  5916.              qendck(Q0,Qnext).
  5917.  
  5918. con(Q0,Con) :- condition(Con).
  5919.  
  5920. con(Q0,Con) :- nl,print(Con,' is an invalid condition. '),
  5921.                flow(Q0).
  5922.  
  5923. condition(verb).
  5924. condition(noun).
  5925. condition(aux).
  5926. condition(prep).
  5927. condition(aux).
  5928. condition(pp).
  5929. condition(np).
  5930.  
  5931.  
  5932. arcck(Q0,Qn,Z)  :-  not(arc(Q0,Qn,Z));
  5933.                     nl,print('Arc from ',Q0,' to ',Qn,' on ',Z,'
  5934.                               exits.').
  5935.  
  5936.  
  5937.                         (c) The predicate 'qendck' verifies that there is a path
  5938. from the end node of the arc just entered to a terminal node.  If not, control
  5939. is passed to 'flow', otherwise 'nextnode' allows a new path to be initiated or
  5940. the program terminated. Pthck is used to verify that there is a path to each of
  5941. the terminal nodes before the program is terminated. Checkstart prevents
  5942. isolated nodes from being inserted into the network.
  5943.  
  5944.  
  5945. qendck(Q0,Qnext)  :- qend(Qnext),(qend(Q0);asserta(qend(Q0))),nextnode.
  5946.  
  5947. qendck(Q0,Qnext)  :-  (qend(Q0);asserta(qend(Q0))),flow(Qnext).
  5948.  
  5949.  
  5950. nextnode :- nl,print('Enter next start node or the word done ? '),
  5951.             read(Ns),
  5952.             not(Ns=done),
  5953.             ((checkstart(Ns),
  5954.             flow(Ns));nextnode).
  5955.  
  5956. ..page
  5957. nextnode :-  pthck,
  5958.              !,retract(term([],[])),
  5959.              nl,print('Network completed'),
  5960.              listing(arc),listing(term),
  5961.              nl,print('Enter name of new ATN file '),read(S),
  5962.              update(node,S),forget(node).
  5963.  
  5964.  
  5965. nextnode :-  nextnode.
  5966.  
  5967.  
  5968. pthck   :-    term(Q,[]),not(Q=[]),not(arc(_,Q,_)),
  5969.               nl,print('No path to terminal node ',Q),
  5970.               !,fail.
  5971.  
  5972. pthck    :-  term([],[]).
  5973.  
  5974.  
  5975. checkstart(Ns) :-  qend(Ns);
  5976.                    nl,print(Ns,' is an invalid node '),fail.
  5977.  
  5978.  
  5979.               2) ATNNEW  One of the features of an ATN vis-a-vis other parsers
  5980. is that the path of transversal can be used to provide information. ATNNEW is an
  5981. example which demonstrates that this can be accomplished in PROLOG. This
  5982. program, which is limited to the ATN in Figure 1, identifies the subject of the
  5983. sentence as the noun (or nouns) in the noun phrase used to transition between
  5984. nodes q0 and q1, or q4 and q5.  It also uses the 'p' or 's' associated with each
  5985. noun or verb and checks the subject and predicate for agreement in number.  The
  5986. code for the predicate ptrans, below, is annotated along the right-hand column
  5987. with numbers to correspond to the notes below.
  5988.  
  5989.  ptrans(Bq,Nq,Lq,[S0|S1],Pr,Parse) :-  S0(Type,Nbr),                       -1
  5990.                                        arc(Bq,Zq,Type),
  5991.         ( ( not(Type=noun); subj(_) ); asserta(subj(Nbr)) ),               -2
  5992.                                        append(Pr,[[Type],S0],P1),
  5993.                                        ptrans(Zq,Nq,Lq,S1,P1,Parse).
  5994.  
  5995. ptrans(Bq,Nq,Lq,S,Pr,Parse)   :-  arc(Bq,Zq,[]),
  5996.                                   ptrans(Zq,Nq,Lq,S,Pr,Parse).
  5997.  
  5998.  
  5999. ptrans(qnp2,Nq,Lq,[S0|S1],Pr,Parse) :-  S0=and,(Lq=q4;Lq=q0),              -3
  6000.                        ( ( subj(_),retract(subj(_)) ); not(subj(_)) ),     -4
  6001.                                         asserta(subj(p)),                  -5
  6002.                                         append(Pr,[and],P1),
  6003.                                         ptrans(qnp,Nq,Lq,S1,P1,Parse).
  6004.  
  6005.  
  6006. ptrans(qnp2,Nq,Lq,[S0|S1],Pr,Parse) :-  S0=and,                            -6
  6007.                                         append(Pr,[and],P1),
  6008.                                         ptrans(qnp,Nq,Lq,S1,P1,Parse).
  6009.  
  6010.  
  6011.  
  6012.  
  6013. ptrans(qnp2,Nq,Lq,S0,Pr,Parse) :-  nl,
  6014.                                    print('Transition ',Lq,' ',Nq),
  6015.                                    nl,
  6016.                                    print(Pr),
  6017.                                    append(Parse,Pr,P1),
  6018.                                    trans(Nq,Rq,P1,S0,S1).
  6019.  
  6020.  
  6021.  
  6022.               -1.  S0 is the next word in the sentence.  Each word is defined as
  6023. a unique fact with a type and number (p or s or x).
  6024. 
  6025.               -2.  This line establishes the number of the subject as that of
  6026. the noun unless one has already been established.  The subject for all sentences
  6027. covered by the ATN in Figure 1 will be located in noun phrases parsed before
  6028. reaching node q2, hence nouns in noun phrases at node q2 or q3 will be ignored.
  6029.  
  6030.               -3.  This predicate is a special provision for the use of 'and' if
  6031. the next word is 'and', and we are attempting to transition from node q4 or q0.
  6032.  
  6033.               -4.  Retract the predicate subj which contains the number for the
  6034. subject.  The not(subj(_)) is actually not required, since the subj has had to
  6035. been asserted if the program gets to this point but is included for balance.
  6036.  
  6037.               -5.  This part of the clause establishes the number associated with
  6038. the subject as plural based on the use of and.
  6039.  
  6040.               -6.  This clause accounts for the case of an and in a noun phrase
  6041. not at node q0 or q4.
  6042.  
  6043. 6.  Conclusions.  The programs developed for this project demonstrate that
  6044. PROLOG is a powerful language that offers unique capabilities and interesting
  6045. potential but little user interface. It is surprising that the power of the
  6046. language has not been exploited to enhance the utility.
  6047.  
  6048.     a.  Any useful application will require some form of procedure.
  6049. Construction of these procedures, such as in the Phase III example, is awkward
  6050. in the current language.
  6051.  
  6052.     b.  Although all variables are local to a predicate, the dynamic nature of
  6053. PROLOG enables the programmer to establish global variables through program
  6054. modification.  It is this feature which appears to offer great potential.
  6055.  
  6056.     c.  There are some alternative search techniques, beyond the scope of this
  6057. paper, which should be evaluated.
  6058.  
  6059.     d.  Given that these examples only employ the most rudimentary PROLOG
  6060. commands, the language appears to offer a rich environment, limited primarily by
  6061. the lack of user interface.
  6062.  
  6063.  
  6064.  
  6065. ..pgno1
  6066. ..foot59c1-##
  6067. /*                 Augmented Transition Network Program
  6068.  
  6069.                                   ATN.PRO
  6070.  
  6071.                                  10/22/85
  6072. */
  6073.  
  6074.  
  6075. /*  Standard routines for append & membership checking       */
  6076.  
  6077.  
  6078. append([],L,L).
  6079. append([Z|L1],L2,[Z|L3]) :- append(L1,L2,L3).
  6080.  
  6081. printstring([]).
  6082. printstring([H|T]) :- put(H), printstring(T).
  6083.  
  6084. member(X,[X|_]).
  6085. member(X,[_|Y]) :- member(X,Y).
  6086.  
  6087.  
  6088. /*  The start module accepts a set of words, enclosed in brackets and
  6089. separated by commas.  It calls wordck to verify that each of the words is
  6090. in the vocabulary set.   */
  6091.  
  6092.  
  6093.  
  6094. start :- batch,nl,print('INPUT'),nl,print('-----'),nl,
  6095.          nl,print('Input sentence: '),read(S),nl,
  6096.          print('The working set is ',S),wordck(S),!,
  6097.          nl,nl,print('TRANSFERS'),nl,nl,print('---------'),nl,nl,q(0,S).
  6098.  
  6099.  
  6100.  
  6101. /*  Wordck checks for the end of the set, [], then if the word is in the
  6102. vocabulary.  If not, it asks for the category, and adds it to the file
  6103. WORD.TEM which is joined with the program after it has run.*/
  6104.  
  6105.  
  6106.  
  6107. wordck([])   :-   !,true.
  6108.  
  6109. wordck([H|T]) :- word(H,Y),wordck(T).
  6110.  
  6111.  
  6112. wordck([H|T]) :-  nl,print(H,' is not a recognized word '),
  6113.                   nl,print(' enter verb,aux, .. '),read(Z),
  6114.                   wordnew(H,Z),wordck(T).
  6115.  
  6116. wordnew(W,Z) :- assertz(word(W,Z)),open('word.tem',ar),
  6117.                 nlf('word.tem'),
  6118.                 printf('word.tem', 'word(', W, ',', Z, ').'),
  6119.                 close('word.tem').
  6120.  
  6121.  
  6122. /*  Trans checks the category of the current word (H) versus the category
  6123. required to make a transition (Z).  */
  6124.  
  6125.  
  6126. trans(H,Z)   :-  word(H,X), member(X,[Z]).
  6127.  
  6128.  
  6129. qfail(Nq,S,E)  :-  !, nl,nl,print('The sentence failed at ',Nq),nl,
  6130.                  print('The sentence form to this node is ',E),nl,
  6131.                  print('The rest of the sentence is ',S),qend1.
  6132.  
  6133.  
  6134. qend(Z,E)  :-  nl,nl,print('OUTPUT'),nl,print('------'),nl,nl,
  6135.                print('The sentence is:'),nl,nl,print(E),nl,nl,
  6136.                print('The sentence is completed at node ',Z),qend1.
  6137.  
  6138.  
  6139. qend1 :- open('word.tem',ar),nlf('word.tem'),
  6140.          close('word.tem'),exec('ren atn.pro atn.sav'),
  6141.          exec('copy atn.sav+word.tem atn.pro'),
  6142.          exec('erase atn.sav'),exec('erase word.tem').
  6143.  
  6144.  
  6145. /*    Print transfer from node to node */
  6146.  
  6147.  
  6148. qout(A,B,C,D,E,F) :- append(E,[C,'(',A,')'],F),
  6149.                      nl, print('Transfer from node ',B,' to node ',D,
  6150.                      ' by word ',A,' evaluated as a ',C).
  6151.  
  6152.  
  6153. /*   Main program to check the conditions for transfer from node to node.
  6154.      The first number is the number of the node, i.e. q(0.. is node 0.
  6155.      The module either checks for a word type and transfers control
  6156.      directly, or passes to np / pp the next node.                    */
  6157.  
  6158.  
  6159. /*  Node 0 - aux to 4 / np to 1 / or fail          */
  6160.  
  6161.  
  6162. q(0,[H|T])  :-  trans(H,[aux]),!,qout(H,0,[aux],4,E,F), q(4,T,F).
  6163.  
  6164. q(0,[H|T])  :-  np(H,T,1,[],0,[np]).
  6165.  
  6166. q(0,S)      :-  qfail(0,S,[]).
  6167.  
  6168.  
  6169. /*  Node 1 - verb to 2 / aux to 5 / or fail    */
  6170.  
  6171.  
  6172. q(1,[H|T],E)  :-  trans(H,[verb]),!,qout(H,1,[verb],2,E,F), q(2,T,F).
  6173.  
  6174. q(1,[H|T],E)  :-  trans(H,[aux]),!, qout(H,1,[aux],5,E,F), q(5,T,F).
  6175.  
  6176. q(1,S,E)      :-  qfail(1,S,E).
  6177.  
  6178. /*  Node 2 -  null to end / np to 2 / pp to 3 / or fail     */
  6179.  
  6180.  
  6181. q(2,H,E)      :- member(H,[[]]), !,
  6182.                    qend(2,E).
  6183.  
  6184. q(2,[H|T],E)  :-  np(H,T,2,E,2,[np]).
  6185.  
  6186.  
  6187. q(2,[H|T],E)  :-  pp(H,T,3,E,2,[pp]).
  6188.  
  6189. q(2,S,E)      :-  qfail(2,S,E).
  6190.  
  6191.  
  6192. /*  Node 3 - null to end / or fail         */
  6193.  
  6194.  
  6195. q(3,H,E)  :- trans(H,[]), !,
  6196.              qend(3,E).
  6197.  
  6198. q(3,S,E)      :-  qfail(3,S,E).
  6199.  
  6200.  
  6201.  
  6202. /*  Node 4 - np to 5 / or fail           */
  6203.  
  6204.  
  6205. q(4,[H|T],E)  :-  np(H,T,5,E,4,[np]).
  6206.  
  6207. q(4,S,E)      :-  qfail(4,S,E).
  6208.  
  6209.  
  6210.  
  6211. /*  Node 5 - verb to 2 / or fail         */
  6212.  
  6213.  
  6214. q(5,[H|T],E)  :-  trans(H,[verb]),!, qout(H,5,[verb],2,E,F), q(2,T,F).
  6215.  
  6216. q(5,S,E)      :-  qfail(5,S,E).
  6217.  
  6218.  
  6219.  
  6220. /*  Noun phrase -  (det) (adj) (adj) .. noun        */
  6221.  
  6222. /*  The np1 clause is required to allow recursive calls for adj   */
  6223.  
  6224.  
  6225. np(H,[S|T],Nq,E,Lq,G)  :-  trans(H,[det]), !,
  6226.                            append(G,['det(',H,')'],G1),
  6227.                            np1([S|T],Nq,E,Lq,G1).
  6228.  
  6229.  
  6230. np(H,Z,Nq,E,Lq,G)      :-  np1([H|Z],Nq,E,Lq,G).
  6231.  
  6232.  
  6233.  
  6234. np1([H|T],Nq,E,Lq,G)  :-  trans(H,[adj]),
  6235.                           append(G,['adj(',H,')'],G1),
  6236.                           np1(T,Nq,E,Lq,G1).
  6237.  
  6238.  
  6239. np1([H|T],Nq,E,Lq,G)  :- trans(H,[noun]),!,nl,
  6240.                          append(G,['noun(',H,')'],G1),
  6241.                          append(E,G1,F),
  6242.                          print('Transfer from node ',Lq,' to ',Nq),
  6243.                          print(' by ',G1),q(Nq,T,F).
  6244.  
  6245.  
  6246. /*  Prep phrase requires a prep followed by a np   */
  6247.  
  6248.  
  6249. pp(H,[S|T],Nq,E,Lq,G)  :-  trans(H,[prep]),
  6250.                            append(['prep(',H,')'],G,G1),
  6251.                            np(S,T,Nq,E,Lq,G1).
  6252.  
  6253.  
  6254. /*   Word defines the vocabulary set                  */
  6255.  
  6256.  
  6257. word(the,[det]).
  6258. word(boy,[noun]).
  6259. word(runs,[verb]).
  6260. word(happy,[adj]).
  6261. word(john,[noun]).
  6262. word(can,[aux]).
  6263. word(run,[verb]).
  6264. word(a,[det]).
  6265. word(big,[adj]).
  6266. word(small,[adj]).
  6267. word(girl,[noun]).
  6268. word(dog,[noun]).
  6269. word(on,[prep]).
  6270. word(pretty,[adj]).
  6271. word(fast,[adj]).
  6272. word(barks,[verb]).
  6273. word(to,[prep]).
  6274. word([],[]).
  6275. word(giant, [noun]).
  6276. word(is, [verb]).
  6277. word(giant, [noun]).
  6278. word(is, [verb]).
  6279. word(sleeps, [verb]).
  6280. word(mary, [noun]).
  6281. word(likes, [verb]).
  6282.  
  6283. ..pgno1
  6284. ..foot59c2-##
  6285. /*                 Augmented Transition Network Program
  6286.  
  6287.                                 ATNREV.PRO
  6288.  
  6289.                                  11/24/85
  6290. */
  6291.  
  6292.  
  6293. /*  Standard routines for append & membership checking       */
  6294.  
  6295.  
  6296. append([],L,L).
  6297. append([Z|L1],L2,[Z|L3]) :- append(L1,L2,L3).
  6298.  
  6299. printstring([]).
  6300. printstring([H|T]) :- put(H), printstring(T).
  6301.  
  6302. member(X,[X|_]).
  6303. member(X,[_|Y]) :- member(X,Y).
  6304.  
  6305.  
  6306. /*  The start module accepts a set of words, enclosed in brackets and
  6307. separated by commas.  It calls wordck to verify that each of the words is
  6308. in the vocabulary set.   */
  6309.  
  6310.  
  6311. start :- batch,nl,print('INPUT'),nl,print('-----'),nl,
  6312.          nl,print('Input sentence: '),read(S),nl,
  6313.          print('The working set is ',S),wordck(S),!,
  6314.          nl,nl,print('TRANSFERS'),nl,nl,print('---------'),nl,nl,
  6315.          Parse=[],
  6316.          trans(q0,Nq,Parse,S,S1).
  6317.  
  6318.  
  6319. /*  Wordck checks for the end of the set, [], then if the word is in the
  6320. vocabulary.  If not, it asks for the category, and adds it to the file
  6321. WORD.TEM which is joined with the program after it has run.*/
  6322.  
  6323.  
  6324. wordck([])   :-   !,true.
  6325.  
  6326. wordck([H|T]) :- word(H,_,_),wordck(T).
  6327.  
  6328.  
  6329. wordck([H|T]) :-  nl,print(H,' is not a recognized word '),
  6330.                   nl,print(' enter verb,aux, .. '),read(Z),
  6331.                   wordnew(H,Z),wordck(T).
  6332.  
  6333. wordnew(W,Z) :- assertz(word(W,Z,s)),open('word.tem',ar),
  6334.                 nlf('word.tem'),
  6335.                 printf('word.tem', 'word(', W, ',', Z, ').'),
  6336.  
  6337.  
  6338.  
  6339.  
  6340. /*  The arcs are defined in terms of from node, to node, condition.
  6341. Terminal nodes are identified with the empty list.  Words are defined by
  6342. type word name, type, and a character to be used in later examples with the
  6343. number (plural or singular).  */
  6344.  
  6345.  
  6346. arc(q0,q1,np).
  6347. arc(q1,q2,verb).
  6348. arc(q2,q2,np).
  6349. arc(q2,q3,pp).
  6350. arc(q0,q4,aux).
  6351. arc(q4,q5,np).
  6352. arc(q1,q5,aux).
  6353. arc(q5,q2,verb).
  6354.  
  6355. term(q2,[]).
  6356. term(q3,[]).
  6357.  
  6358.  
  6359. word(boy,noun,s).
  6360. word(boys,noun,pl).
  6361. word(run,verb,pl).
  6362. word(runs,verb,s).
  6363. word(the,det,s).
  6364.  
  6365. arc(qnp,qnp1,det).
  6366. arc(qnp,qnp1,_).
  6367. arc(qnp1,qnp1,adj).
  6368. arc(qnp1,qnp2,noun).
  6369. arc(qpp,qnp,prep).
  6370.  
  6371.  
  6372. /*  Trans recursively checks the conditions for transition from the last
  6373. node (Lq) to the next node (Nq).  Phrases are specifically treated as pp or
  6374. np in order to allow the type of phrase to be identified in the parsed
  6375. sentence.  */
  6376.  
  6377.  
  6378. trans(Lq,_,Parse,S1,_) :- term(Lq,S1),nl,
  6379.                           print('Completed ',Lq),
  6380.                           nl,print(Parse).
  6381.  
  6382.  
  6383. trans(Lq,Nq,Parse,[S0|S1],S1) :-  word(S0,Type,Nbr),
  6384.                                   arc(Lq,Nq,Type),
  6385.                                   nl,
  6386.                                   print('Transition ',Lq,' ',Nq,' ',S0,
  6387.                                             ' ',Type),
  6388.                                   append(Parse,[[Type],S0],P1),
  6389.                                   !,
  6390.                                   trans(Nq,Z,P1,S1,S2).
  6391.  
  6392.  
  6393. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,np),
  6394.                              ptrans(qnp,Nq,Lq,S0,[np],Parse).
  6395.  
  6396.  
  6397. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,pp),
  6398.                              ptrans(qpp,Nq,Lq,S0,[pp],Parse).
  6399.  
  6400.  
  6401.  
  6402. trans(Lq,Nq,Parse,S0,S1) :- !,nl,
  6403.                             print('The sentence failed at ',Lq),
  6404.                             nl,print('Parsed ',Parse),
  6405.                             nl,print('Left ',S0).
  6406.  
  6407. /*  Ptrans checks the transition of the phrase network.  The first clause
  6408. calls itself recursively until node qnp2 has been reached, which concludes
  6409. the transition.  Success results in trans being called  with the new node.
  6410. Failure returns the trans with conditions unchanged.  */
  6411.  
  6412.  
  6413. ptrans(Bq,Nq,Lq,[S0|S1],Pr,Parse) :-  word(S0,Type,Nbr),
  6414.                                 arc(Bq,Zq,Type),
  6415.                                 append(Pr,[[Type],S0],P1),
  6416.                                 !,
  6417.                                 ptrans(Zq,Nq,Lq,S1,P1,Parse).
  6418.  
  6419. ptrans(qnp2,Nq,Lq,S0,Pr,Parse) :-  nl,
  6420.                                    print('Transition ',Lq,' ',Nq),
  6421.                                    nl,
  6422.                                    print(Pr),
  6423.                                    append(Parse,Pr,P1),
  6424.                                    !,
  6425.                                    trans(Nq,Rq,P1,S0,S1).
  6426.  
  6427. ..page
  6428. ..pgno1
  6429. ..foot59c3-##
  6430. /*        PROGRAM TO BUILD PRIMARY AUGMENTED TRANSITION NETWORK
  6431.  
  6432.                                 ATNBLD.PRO
  6433.  
  6434.                                  11/24/85
  6435.  
  6436. */
  6437.  
  6438.  
  6439. /*  Build is the entry point into the program.  It requires that the
  6440. program with standard routines and the program node, which is empty, have
  6441. already been consulted.  */
  6442.  
  6443. /*  The program requests the start and terminal nodes, the paths and
  6444. transition conditions, then establishes a node program with a name
  6445. specified by the user.  */
  6446.  
  6447. /*  Ret removes any data from memory which might interfere with network
  6448. construction.  Term([],[]) is required to prevent failure when checkint
  6449. terminal conditions.  Qend identifies all nodes for which there is a path
  6450. to a terminal node.  The start node is identified initially since the
  6451. program will require this path be completed before any other can be
  6452. constructed.  Termnode accepts the terminal nodes.  Flow accepts the
  6453. transition arcs and conditions.  */
  6454.  
  6455.  
  6456. build :- batch,ret(qend),nl,ret(arc),nl,ret(term),asserta(term([],[])),
  6457.          nl,print('Enter the start node: '),read(Q0),
  6458.          asserta(qend(Q0)),termnode,flow(Q0).
  6459.  
  6460.  
  6461. termnode :-  print('Enter the next terminal node or the word done: '),
  6462.              read(QT),
  6463.              not(QT=done),
  6464.              termck(QT),
  6465.              assertfa(node,term(QT,[])),
  6466.              asserta(qend(QT)),
  6467.              termnode.
  6468.  
  6469. termnode  :-  !,true.
  6470.  
  6471.  
  6472. /*  Flow requests transitions from node to node and adds each arc and new
  6473. node to the database.  Qendck will continue to call flow until such time as
  6474. a terminal node has been reached then allow a new path to be initiated.  */
  6475.  
  6476.  
  6477.  
  6478. flow(Q0)  :- nl,print('Transition from ',Q0,' to ? '),read(Qnext),
  6479.              print(' on condition ? '),read(Con),
  6480.              con(Q0,Con),arcck(Q0,Qnext,Con),
  6481.              assertfz(node,arc(Q0,Qnext,Con)),
  6482.              qendck(Q0,Qnext).
  6483.  
  6484. con(Q0,Con) :- condition(Con).
  6485.  
  6486. con(Q0,Con) :- nl,print(Con,' is an invalid condition. '),
  6487.                flow(Q0).
  6488.  
  6489. termck(Qt)  :-  not(term(Qt,[]));
  6490.                 nl,print('Terminal node ',Qt,' already entered'),nl.
  6491.  
  6492. arcck(Q0,Qn,Z)  :-  not(arc(Q0,Qn,Z));
  6493.                     nl,print('Arc from ',Q0,' to ',Qn,' on ',Z,' exits.').
  6494.  
  6495. qendck(Q0,Qnext)  :-  qend(Qnext),(qend(Q0);asserta(qend(Q0))),nextnode.
  6496.  
  6497. qendck(Q0,Qnext)  :-  (qend(Q0);asserta(qend(Q0))),flow(Qnext).
  6498.  
  6499.  
  6500. /*  Nextnode allows a new path to be initiated or the program to be
  6501. terminated.  Before termination it calls pthck to insure there is a path to
  6502. each terminal node.  Checkstart prevents an isolated node from being
  6503. entered.  */
  6504.  
  6505. nextnode :-  nl,print('Enter next start node or the word done ? '),
  6506.              read(Ns),
  6507.              not(Ns=done),
  6508.              ((checkstart(Ns),
  6509.              flow(Ns));nextnode).
  6510.  
  6511. nextnode :-  pthck,
  6512.              !,retract(term([],[])),
  6513.              nl,print('Network completed'),
  6514.              listing(arc),listing(term),
  6515.              nl,print('Enter name of new ATN file '),read(S),
  6516.              update(node,S).
  6517.  
  6518. nextnode :-  nextnode.
  6519.  
  6520. pthck   :-    term(Q,[]),not(Q=[]),not(arc(_,Q,_)),
  6521.               nl,print('No path to terminal node ',Q),
  6522.               !,fail.
  6523.  
  6524. pthck    :-  term([],[]).
  6525.  
  6526. checkstart(Ns) :-  qend(Ns);
  6527.                    nl,print(Ns,' is an invalid node '),fail.
  6528.  
  6529. /*  Condition lists the acceptable conditions for a transition.   */
  6530.  
  6531. condition(verb).
  6532. condition(noun).
  6533. condition(aux).
  6534. condition(prep).
  6535. condition(aux).
  6536. condition(pp).
  6537. condition(np).
  6538. ..pgno1
  6539. ..foot59c4-##
  6540. /*              FINAL AUGMENTED TRANSITION NETWORK PROGRAM
  6541.  
  6542.                                 ATNNEW1.PRO
  6543.  
  6544.                                  11/24/85
  6545. */
  6546.  
  6547.  
  6548. /*  Start is the entry into the program.  It requires that a set of
  6549. standard routines has already been consulted (append in particular).  It
  6550. allows the user to specify the network program, which can be build using
  6551. ATNBLD.  Words is a file with the vocabulary set.  The sentences is a list
  6552. of words separated by commas and enclosed in brackets.  Wordck verifies
  6553. that the words are in the vocabulary set, and if not requests required
  6554. data. Parse is the sentence as it is parsed.  Trans controls the flow from
  6555. node to node.  */
  6556.  
  6557. start :- nl,print('ATN network file? '),read(Fn),
  6558.          consult(Fn),nl,
  6559.          asserta(file(Fn)),
  6560.          consult(words),nl,
  6561.          batch,nl,print('INPUT'),nl,print('-----'),nl,
  6562.          nl,print('Input sentence: '),read(S),nl,
  6563.          print('The working set is ',S),wordck(S),
  6564.          nl,nl,print('TRANSFERS'),nl,nl,print('---------'),nl,nl,
  6565.          Parse=[],
  6566.          trans(q0,Nq,Parse,S,S1).
  6567.  
  6568.  
  6569. wordck([])   :-   true.
  6570.  
  6571. wordck([H|T]) :- H(_,_),wordck(T).
  6572.  
  6573. wordck([H|T]) :-  nl,print(H,' is not a recognized word '),
  6574.                   nl,print(' enter verb,aux, .. '),read(Z),
  6575.                   nl,print(' enter p or s or x  '),read(Z1),
  6576.                   wordnew(H,Z,Z1),wordck(T).
  6577.  
  6578. wordnew(W,Z,Z1) :- assertfz(words,W(Z,Z1)).
  6579.  
  6580.  
  6581. /*  Since the phrase transition network includes more specific procedures
  6582. than the primary network, it is included in this program rather than in the
  6583. network file consulted by start.  It could be more dynamic, but that was
  6584. considered beyond the scope of this project.  */
  6585.  
  6586.  
  6587. arc(qnp,qnp1,det).
  6588. arc(qnp,qnp1,[]).
  6589. arc(qnp1,qnp1,adj).
  6590. arc(qnp1,qnp2,noun).
  6591. arc(qpp,qnp,prep).
  6592.  
  6593.  
  6594. /*  Trans controls the flow along the network.  If a terminal node has been
  6595. reached and the entire sentence has been parsed, the agreement in number
  6596. (plural or singular) between the subject and predicate is checked.  If they
  6597. do not agree, this fact is displayed.  Update words creates a file
  6598. WORDS.$$$ which contains the new vocabulary.
  6599.  
  6600. If a conditions for termination has not been met, trans checks for a
  6601. transition word or a transition phrase.  If none of these conditions are
  6602. met, the sentence will not parse.
  6603.  
  6604. When a verb is encountered the number (singular or plural) is 'filed'.
  6605. This procedure is unique for a specific network in which only one verb can
  6606. be encountered.  */
  6607.  
  6608. trans(Lq,_,Parse,S1,_) :- term(Lq,S1),nl,
  6609.                           print('Completed ',Lq),
  6610.                           nl,print(Parse),
  6611.                        (  ( subj(Nbr),pred(Nbr) );
  6612.                       (nl,print('The subject and predicate do not agree.')
  6613.                           ) ),
  6614.                           update(words),
  6615.                           exec('erase words.pro'),
  6616.                           exec('ren words.$$$ words.pro'),
  6617.                           forget(words),
  6618.                           file(Fn),
  6619.                           forget(Fn),
  6620.                           endclr.
  6621.  
  6622. endclr :-  (not(file(_));ret(file)),(not(subj(_));ret(subj)),
  6623.            (not(pred(_));ret(pred)).
  6624.  
  6625.  
  6626. trans(Lq,Nq,Parse,[S0|S1],S1) :-  S0(Type,Nbr),
  6627.                                   arc(Lq,Nq,Type),
  6628.                                  ((Type=verb,asserta(pred(Nbr)));
  6629.                                      not(type=verb)),
  6630.                                   nl,
  6631.                                   print('Transition ',Lq,' ',Nq,' ',S0,
  6632.                                             ' ',Type),
  6633.                                   append(Parse,[[Type],S0],P1),
  6634.                                   trans(Nq,Z,P1,S1,S2).
  6635.  
  6636.  
  6637. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,np),
  6638.                              ptrans(qnp,Nq,Lq,S0,[' '+np],Parse).
  6639.  
  6640. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,pp),
  6641.                              ptrans(qpp,Nq,Lq,S0,[' '+pp],Parse).
  6642.  
  6643. trans(Lq,Nq,Parse,S0,S1) :- nl,
  6644.                             print('The sentence failed at ',Lq),
  6645.                             nl,print('Parsed ',Parse),
  6646.                             nl,print('Left ',S0),
  6647.                             endclr.
  6648. /*  Ptrans checks the transition of the phrase network.  It calls itself
  6649. recursively until node qnp2 is reached.  Provisions are included to
  6650. establish the number (plural or singular) of the subject, which is designed
  6651. for a specific network in which the noun phrase in which the subject is
  6652. located will be encountered before any other noun phrase.
  6653.  
  6654. The upon reaching qnp2 a check is made for the word 'and'.  If encountered,
  6655. the number of the subject is changed to plural and a check for another noun
  6656. phrase is initiated.
  6657.  
  6658. The spacing of the parenthesis is to facilitate reading of the code.  */
  6659.  
  6660.  
  6661. ptrans(Bq,Nq,Lq,[S0|S1],Pr,Parse) :-  S0(Type,Nbr),
  6662.                                 arc(Bq,Zq,Type),
  6663.                           (
  6664.                              (
  6665.                                  not(Type=noun);
  6666.  
  6667.                                  subj(_)
  6668.                                           );
  6669.                                  asserta(subj(Nbr))
  6670.                                                   ),
  6671.                                 append(Pr,[[Type],S0],P1),
  6672.                                 ptrans(Zq,Nq,Lq,S1,P1,Parse).
  6673.  
  6674. ptrans(Bq,Nq,Lq,S,Pr,Parse)   :-  arc(Bq,Zq,[]),
  6675.                                   ptrans(Zq,Nq,Lq,S,Pr,Parse).
  6676.  
  6677.  
  6678. ptrans(qnp2,Nq,Lq,[S0|S1],Pr,Parse) :-  S0=and,(Lq=q4;Lq=q0),
  6679.                                        ( ( subj(_),retract(subj(_)) );
  6680.                                          not(subj(_)) ),
  6681.                                          asserta(subj(p)),
  6682.                                           append(Pr,[and],P1),
  6683.                                           ptrans(qnp,Nq,Lq,S1,P1,Parse).
  6684.  
  6685.  
  6686. ptrans(qnp2,Nq,Lq,[S0|S1],Pr,Parse) :-  S0=and,
  6687.                                           append(Pr,[and],P1),
  6688.                                           ptrans(qnp,Nq,Lq,S1,P1,Parse).
  6689.  
  6690.  
  6691.  
  6692.  
  6693. ptrans(qnp2,Nq,Lq,S0,Pr,Parse) :-  nl,
  6694.                                    print('Transition ',Lq,' ',Nq),
  6695.                                    nl,
  6696.                                    print(Pr),
  6697.                                    append(Parse,Pr,P1),
  6698.                                    trans(Nq,Rq,P1,S0,S1).
  6699. append([],L,L).
  6700. append([Z|L1],L2,[Z|L3]) :- append(L1,L2,L3).
  6701.  
  6702. printstring([]).
  6703. printstring([H|T]) :- put(H), printstring(T).
  6704.  
  6705. ret(X) :- X(_),retract(X(_)),ret(X).
  6706. ret(X) :- X(_,_),retract(X(_,_)),ret(X).
  6707. ret(X) :- X(_,_,_),retract(X(_,_,_)),ret(X).
  6708. ret(X) :- nl,print(X,' has been retracted').
  6709. /*         final atn program    */
  6710. /*                empty node program          */
  6711. /*        PROGRAM TO BUILD PRIMARY AUGMENTED TRANSISTION NETWORK
  6712.  
  6713.                                 ATNBLD.PRO
  6714.  
  6715.                                  11/24/85
  6716.  
  6717. */
  6718.  
  6719.  
  6720. /*  Build is the entry point into the program.  It requires that the
  6721. program with standard routines and the program node, which is empty, have
  6722. already been consulted.  */
  6723.  
  6724. /*  The program requests the start and terminal nodes, the paths and
  6725. transistion conditions, then establishes a node program with a name
  6726. specified by the user.  */
  6727.  
  6728. /*  Ret removes any data from memory which might iterfere with network
  6729. construction.  Term([],[]) is required to prevent failure when checkint
  6730. terminal conditions.  Qend identifies all nodes for which there is a path
  6731. to a terminal node.  The start node is identified initially since the
  6732. program will require this path be completed before any other can be
  6733. constructed.  Termnode accepts the terminal nodes.  Flow accepts the
  6734. transition arcs and conditions.  */
  6735.  
  6736.  
  6737. build :- batch,ret(qend),nl,ret(arc),nl,ret(term),asserta(term([],[])),
  6738.          nl,print('Enter the start node: '),read(Q0),
  6739.          asserta(qend(Q0)),termnode,flow(Q0).
  6740.  
  6741.  
  6742. termnode :-  print('Enter the next terminal node or the word done: '),
  6743.              read(QT),
  6744.              not(QT=done),
  6745.              termck(QT),
  6746.              assertfa(node,term(QT,[])),
  6747.              asserta(qend(QT)),
  6748.              termnode.
  6749.  
  6750. termnode  :-  !,true.
  6751.  
  6752.  
  6753. /*  Flow requests transistions from node to node and adds each arc and new
  6754. node to the database.  Qendck will continue to call flow until such time as
  6755. a terminal node has been reached then allow a new path to be initiated.  */
  6756.  
  6757.  
  6758.  
  6759. flow(Q0)  :- nl,print('Transisition from ',Q0,' to ? '),read(Qnext),
  6760.              print(' on condition ? '),read(Con),
  6761.              con(Q0,Con),arcck(Q0,Qnext,Con),
  6762.              assertfz(node,arc(Q0,Qnext,Con)),
  6763.              qendck(Q0,Qnext).
  6764.  
  6765. con(Q0,Con) :- condition(Con).
  6766.  
  6767. con(Q0,Con) :- nl,print(Con,' is an invalid condition. '),
  6768.                flow(Q0).
  6769.  
  6770. termck(Qt)  :-  not(term(Qt,[]));
  6771.                 nl,print('Terminal node ',Qt,' already entered'),nl.
  6772.  
  6773. arcck(Q0,Qn,Z)  :-  not(arc(Q0,Qn,Z));
  6774.                     nl,print('Arc from ',Q0,' to ',Qn,' on ',Z,' exits.').
  6775.  
  6776. qendck(Q0,Qnext)  :-  qend(Qnext),(qend(Q0);asserta(qend(Q0))),nextnode.
  6777.  
  6778. qendck(Q0,Qnext)  :-  (qend(Q0);asserta(qend(Q0))),flow(Qnext).
  6779.  
  6780.  
  6781. /*  Nextnode allows a new path to be initiated or the program to be
  6782. terminated.  Before termination it calls pthck to insure there is a path to
  6783. each terminal node.  Checkstart prevents an isolated node from being
  6784. entered.  */
  6785.  
  6786.  
  6787.  
  6788. nextnode :-  nl,print('Enter next start node or the word done ? '),
  6789.              read(Ns),
  6790.              not(Ns=done),
  6791.              ((checkstart(Ns),
  6792.              flow(Ns));nextnode).
  6793.  
  6794.  
  6795. nextnode :-  pthck,
  6796.              !,retract(term([],[])),
  6797.              nl,print('Network completed'),
  6798.              listing(arc),listing(term),
  6799.              nl,print('Enter name of new ATN file '),read(S),
  6800.              update(node,S).
  6801.  
  6802.  
  6803. nextnode :-  nextnode.
  6804.  
  6805.  
  6806. pthck   :-    term(Q,[]),not(Q=[]),not(arc(_,Q,_)),
  6807.               nl,print('No path to terminal node ',Q),
  6808.               !,fail.
  6809.  
  6810. pthck    :-  term([],[]).
  6811.  
  6812.  
  6813. checkstart(Ns) :-  qend(Ns);
  6814.                    nl,print(Ns,' is an invalid node '),fail.
  6815.  
  6816.  
  6817. /*  Condition lists the acceptable conditions for a transistion.   */
  6818.  
  6819.  
  6820. condition(verb).
  6821. condition(noun).
  6822. condition(aux).
  6823. condition(prep).
  6824. condition(aux).
  6825. condition(pp).
  6826. condition(np).
  6827.  
  6828. plane(noun,s).
  6829.  
  6830.  
  6831. green(adj,x).
  6832.  
  6833.  
  6834. gocart(noun,s).
  6835.  
  6836.  
  6837. black(adj,x).
  6838.  
  6839.  
  6840. bikes(noun,p).
  6841.  
  6842.  
  6843. farm(noun,s).
  6844.  
  6845.  
  6846. girls(noun,p).
  6847.  
  6848.  
  6849. car(noun,s).
  6850.  
  6851.  
  6852. rides(verb,s).
  6853.  
  6854.  
  6855. and(conj,x).
  6856.  
  6857.  
  6858. girl(noun,s).
  6859.  
  6860.  
  6861. ran(verb,p).
  6862.  
  6863.  
  6864. big(adj,x).
  6865.  
  6866.  
  6867. bike(noun,s).
  6868.  
  6869.  
  6870. ride(verb,p).
  6871.  
  6872.  
  6873. store(noun,s).
  6874.  
  6875.  
  6876. to(prep,x).
  6877.  
  6878.  
  6879. home(noun,s).
  6880.  
  6881. /*           words file          */
  6882. /*          11/19/85           */
  6883.  
  6884.  
  6885. boy(noun,s).
  6886. boys(noun,p).
  6887. run(verb,p).
  6888. runs(verb,s).
  6889. can(aux,x).
  6890. the(det,s).
  6891. /*                 Augmented Transition Network Program
  6892.  
  6893.                                 ATNREV.PRO
  6894.  
  6895.                                  11/24/85
  6896. */
  6897.  
  6898.  
  6899. /*  Standard routines for append & membership checking       */
  6900.  
  6901.  
  6902. append([],L,L).
  6903. append([Z|L1],L2,[Z|L3]) :- append(L1,L2,L3).
  6904.  
  6905. printstring([]).
  6906. printstring([H|T]) :- put(H), printstring(T).
  6907.  
  6908. member(X,[X|_]).
  6909. member(X,[_|Y]) :- member(X,Y).
  6910.  
  6911.  
  6912. /*  The start module accepts a set of words, enclosed in brackets and
  6913. separated by commas.  It calls wordck to verify that each of the words is
  6914. in the vocuabulary set.   */
  6915.  
  6916.  
  6917.  
  6918. start :- batch,nl,print('INPUT'),nl,print('-----'),nl,
  6919.          nl,print('Input sentence: '),read(S),nl,
  6920.          print('The working set is ',S),wordck(S),!,
  6921.          nl,nl,print('TRANSFERS'),nl,nl,print('---------'),nl,nl,
  6922.          Parse=[],
  6923.          trans(q0,Nq,Parse,S,S1).
  6924.  
  6925.  
  6926. /*  Wordck checks for the end of the set, [], then if the word is in the
  6927. vocabulary.  If not, it asks for the catagory, and adds it to the file
  6928. WORD.TEM which is joined with the program after it has run.*/
  6929.  
  6930.  
  6931.  
  6932.  
  6933.  
  6934. wordck([])   :-   !,true.
  6935.  
  6936. wordck([H|T]) :- word(H,_,_),wordck(T).
  6937.  
  6938.  
  6939. wordck([H|T]) :-  nl,print(H,' is not a recognized word '),
  6940.                   nl,print(' enter verb,aux, .. '),read(Z),
  6941.                   wordnew(H,Z),wordck(T).
  6942.  
  6943. wordnew(W,Z) :- assertz(word(W,Z,s)),open('word.tem',ar),
  6944.                 nlf('word.tem'),
  6945.                 printf('word.tem', 'word(', W, ',', Z, ').'),
  6946.                 close('word.tem').
  6947.  
  6948.  
  6949.  
  6950.  
  6951. /*  The arcs are defined in terms of from node, to node, condition.
  6952. Terminal nodes are identified with the empty list.  Words are defined by
  6953. type word name, type, and a character to be used in later examples with the
  6954. number (plural or singular).  */
  6955.  
  6956.  
  6957. arc(q0,q1,np).
  6958. arc(q1,q2,verb).
  6959. arc(q2,q2,np).
  6960. arc(q2,q3,pp).
  6961. arc(q0,q4,aux).
  6962. arc(q4,q5,np).
  6963. arc(q1,q5,aux).
  6964. arc(q5,q2,verb).
  6965.  
  6966. term(q2,[]).
  6967. term(q3,[]).
  6968.  
  6969.  
  6970. word(boy,noun,s).
  6971. word(boys,noun,pl).
  6972. word(run,verb,pl).
  6973. word(runs,verb,s).
  6974. word(the,det,s).
  6975.  
  6976. arc(qnp,qnp1,det).
  6977. arc(qnp,qnp1,_).
  6978. arc(qnp1,qnp1,adj).
  6979. arc(qnp1,qnp2,noun).
  6980. arc(qpp,qnp,prep).
  6981.  
  6982.  
  6983. /*  Trans recursively checks the conditions for transistion from the last
  6984. node (Lq) to the next node (Nq).  Phrases are specifically treated as pp or
  6985. np in order to allow the type of phrase to be identified in the parsed
  6986. sentence.  */
  6987.  
  6988.  
  6989.  
  6990.  
  6991. trans(Lq,_,Parse,S1,_) :- term(Lq,S1),nl,
  6992.                           print('Completed ',Lq),
  6993.                           nl,print(Parse).
  6994.  
  6995.  
  6996. trans(Lq,Nq,Parse,[S0|S1],S1) :-  word(S0,Type,Nbr),
  6997.                                   arc(Lq,Nq,Type),
  6998.                                   nl,
  6999.                                   print('Transition ',Lq,' ',Nq,' ',S0,
  7000.                                             ' ',Type),
  7001.                                   append(Parse,[[Type],S0],P1),
  7002.                                   !,
  7003.                                   trans(Nq,Z,P1,S1,S2).
  7004.  
  7005.  
  7006. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,np),
  7007.                              ptrans(qnp,Nq,Lq,S0,[np],Parse).
  7008.  
  7009.  
  7010. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,pp),
  7011.                              ptrans(qpp,Nq,Lq,S0,[pp],Parse).
  7012.  
  7013.  
  7014.  
  7015. trans(Lq,Nq,Parse,S0,S1) :- !,nl,
  7016.                             print('The sentence failed at ',Lq),
  7017.                             nl,print('Parsed ',Parse),
  7018.                             nl,print('Left ',S0).
  7019.  
  7020. /*  Ptrans checks the transistion of the phrase network.  The first clause
  7021. calls itself recursively until node qnp2 has been reached, which concludes
  7022. the transistion.  Success results in trans being called  with the new node.
  7023. Failure returns the trans with conditions unchanged.  */
  7024.  
  7025.  
  7026.  
  7027. ptrans(Bq,Nq,Lq,[S0|S1],Pr,Parse) :-  word(S0,Type,Nbr),
  7028.                                 arc(Bq,Zq,Type),
  7029.                                 append(Pr,[[Type],S0],P1),
  7030.                                 !,
  7031.                                 ptrans(Zq,Nq,Lq,S1,P1,Parse).
  7032.  
  7033. ptrans(qnp2,Nq,Lq,S0,Pr,Parse) :-  nl,
  7034.                                    print('Transisiton ',Lq,' ',Nq),
  7035.                                    nl,
  7036.                                    print(Pr),
  7037.                                    append(Parse,Pr,P1),
  7038.                                    !,
  7039.                                    trans(Nq,Rq,P1,S0,S1).
  7040. /*              FINAL AUGMENTED TRANSISTION NETWORK PROGRAM
  7041.  
  7042.                                 ATNNEW1.PRO
  7043.  
  7044.                                  11/24/85
  7045. */
  7046.  
  7047.  
  7048. /*  Start is the entry into the program.  It requires that a set of
  7049. standard routines has already been consulted (append in particular).  It
  7050. allows the user to specify the network program, which can be build using
  7051. ATNBLD.  Words is a file with the vocabulary set.  The sentences is a list
  7052. of words separated by commas and enclosed in brackets.  Wordck verifies
  7053. that the words are in the vocabulary set, and if not requests required
  7054. data. Parse is the sentence as it is parsed.  Trans controls the flow from
  7055. node to node.  */
  7056.  
  7057.  
  7058. start :- nl,print('ATN network file? '),read(Fn),
  7059.          consult(Fn),nl,
  7060.          asserta(file(Fn)),
  7061.          consult(words),nl,
  7062.          batch,nl,print('INPUT'),nl,print('-----'),nl,
  7063.          nl,print('Input sentence: '),read(S),nl,
  7064.          print('The working set is ',S),wordck(S),
  7065.          nl,nl,print('TRANSFERS'),nl,nl,print('---------'),nl,nl,
  7066.          Parse=[],
  7067.          trans(q0,Nq,Parse,S,S1).
  7068.  
  7069.  
  7070.  
  7071. wordck([])   :-   true.
  7072.  
  7073. wordck([H|T]) :- H(_,_),wordck(T).
  7074.  
  7075.  
  7076. wordck([H|T]) :-  nl,print(H,' is not a recognized word '),
  7077.                   nl,print(' enter verb,aux, .. '),read(Z),
  7078.                   nl,print(' enter p or s or x  '),read(Z1),
  7079.                   wordnew(H,Z,Z1),wordck(T).
  7080.  
  7081. wordnew(W,Z,Z1) :- assertfz(words,W(Z,Z1)).
  7082.  
  7083.  
  7084. /*  Since the phrase transition network includes more specific procedures
  7085. than the primary network, it is included in this program rather than in the
  7086. network file consulted by start.  It could be more dynamic, but that was
  7087. considered beyond the scope of this project.  */
  7088.  
  7089.  
  7090. arc(qnp,qnp1,det).
  7091. arc(qnp,qnp1,[]).
  7092. arc(qnp1,qnp1,adj).
  7093. arc(qnp1,qnp2,noun).
  7094. arc(qpp,qnp,prep).
  7095.  
  7096.  
  7097. /*  Trans controls the flow along the network.  If a terminal node has been
  7098. reached and the entire sentence has been parsed, the agreement in number
  7099. (plural or singular) between the subject and predicate is checked.  If they
  7100. do not agree, this fact is displayed.  Update words creates a file
  7101. WORDS.$$$ which contains the new vocabulary.
  7102.  
  7103. If a conditions for termination has not been met, trans checks for a
  7104. transition word or a transistion phrase.  If none of these conditions are
  7105. met, the sentence will not parse.
  7106.  
  7107. When a verb is encountered the number (singular or plural) is 'filed'.
  7108. This procedure is unique for a specific network in which only one verb can
  7109. be encountered.  */
  7110.  
  7111.  
  7112. trans(Lq,_,Parse,S1,_) :- term(Lq,S1),nl,
  7113.                           print('Completed ',Lq),
  7114.                           nl,print(Parse),
  7115.                        (  ( subj(Nbr),pred(Nbr) );
  7116.                       (nl,print('The subject and predicate do not agree.')
  7117.                           ) ),
  7118.                           update(words),
  7119.                           exec('erase words.pro'),
  7120.                           exec('ren words.$$$ words.pro'),
  7121.                           forget(words),
  7122.                           file(Fn),
  7123.                           forget(Fn),
  7124.                           endclr.
  7125.  
  7126.  
  7127. endclr :-  (not(file(_));ret(file)),(not(subj(_));ret(subj)),
  7128.            (not(pred(_));ret(pred)).
  7129.  
  7130.  
  7131. trans(Lq,Nq,Parse,[S0|S1],S1) :-  S0(Type,Nbr),
  7132.                                   arc(Lq,Nq,Type),
  7133.                                  ((Type=verb,asserta(pred(Nbr)));
  7134.                                      not(type=verb)),
  7135.                                   nl,
  7136.                                   print('Transition ',Lq,' ',Nq,' ',S0,
  7137.                                             ' ',Type),
  7138.                                   append(Parse,[[Type],S0],P1),
  7139.                                   trans(Nq,Z,P1,S1,S2).
  7140.  
  7141.  
  7142. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,np),
  7143.                              ptrans(qnp,Nq,Lq,S0,[' '+np],Parse).
  7144.  
  7145.  
  7146. trans(Lq,Nq,Parse,S0,S1) :-  arc(Lq,Nq,pp),
  7147.                              ptrans(qpp,Nq,Lq,S0,[' '+pp],Parse).
  7148.  
  7149.  
  7150.  
  7151. trans(Lq,Nq,Parse,S0,S1) :- nl,
  7152.                             print('The sentence failed at ',Lq),
  7153.                             nl,print('Parsed ',Parse),
  7154.                             nl,print('Left ',S0),
  7155.                             endclr.
  7156.  
  7157.  
  7158.  
  7159. /*  Ptrans checks the transition of the phrase network.  It calls itself
  7160. recursively until node qnp2 is reached.  Provisions are included to
  7161. establish the number (plural or singular) of the subject, which is designed
  7162. for a specific network in which the noun phrase in which the subject is
  7163. located will be encountered before any other noun phrase.
  7164.  
  7165. The upon reaching qnp2 a check is made for the word 'and'.  If encountered,
  7166. the number of the subject is changed to plural and a check for another noun
  7167. phrase is initiated.
  7168.  
  7169. The spacing of the parathesis is to faciltiate reading of the code.  */
  7170.  
  7171.  
  7172. ptrans(Bq,Nq,Lq,[S0|S1],Pr,Parse) :-  S0(Type,Nbr),
  7173.                                 arc(Bq,Zq,Type),
  7174.                           (
  7175.                              (
  7176.                                  not(Type=noun);
  7177.  
  7178.                                  subj(_)
  7179.                                           );
  7180.                                  asserta(subj(Nbr))
  7181.                                                   ),
  7182.                                 append(Pr,[[Type],S0],P1),
  7183.                                 ptrans(Zq,Nq,Lq,S1,P1,Parse).
  7184.  
  7185. ptrans(Bq,Nq,Lq,S,Pr,Parse)   :-  arc(Bq,Zq,[]),
  7186.                                   ptrans(Zq,Nq,Lq,S,Pr,Parse).
  7187.  
  7188.  
  7189. ptrans(qnp2,Nq,Lq,[S0|S1],Pr,Parse) :-  S0=and,(Lq=q4;Lq=q0),
  7190.                                        ( ( subj(_),retract(subj(_)) );
  7191.                                          not(subj(_)) ),
  7192.                                          asserta(subj(p)),
  7193.                                           append(Pr,[and],P1),
  7194.                                           ptrans(qnp,Nq,Lq,S1,P1,Parse).
  7195.  
  7196.  
  7197. ptrans(qnp2,Nq,Lq,[S0|S1],Pr,Parse) :-  S0=and,
  7198.                                           append(Pr,[and],P1),
  7199.                                           ptrans(qnp,Nq,Lq,S1,P1,Parse).
  7200.  
  7201.  
  7202.  
  7203.  
  7204. ptrans(qnp2,Nq,Lq,S0,Pr,Parse) :-  nl,
  7205.                                    print('Transisiton ',Lq,' ',Nq),
  7206.                                    nl,
  7207.                                    print(Pr),
  7208.                                    append(Parse,Pr,P1),
  7209.                                    trans(Nq,Rq,P1,S0,S1).
  7210. /*                 Augmented Transition Network Program
  7211.  
  7212.                                   ATN.PRO
  7213.  
  7214.                                  10/22/85
  7215. */
  7216.  
  7217.  
  7218. /*  Standard routines for append & membership checking       */
  7219.  
  7220.  
  7221. append([],L,L).
  7222. append([Z|L1],L2,[Z|L3]) :- append(L1,L2,L3).
  7223.  
  7224. printstring([]).
  7225. printstring([H|T]) :- put(H), printstring(T).
  7226.  
  7227. member(X,[X|_]).
  7228. member(X,[_|Y]) :- member(X,Y).
  7229.  
  7230.  
  7231. /*  The start module accepts a set of words, enclosed in brackets and
  7232. separated by commas.  It calls wordck to verify that each of the words is
  7233. in the vocuabulary set.   */
  7234.  
  7235.  
  7236.  
  7237. start :- batch,nl,print('INPUT'),nl,print('-----'),nl,
  7238.          nl,print('Input sentence: '),read(S),nl,
  7239.          print('The working set is ',S),wordck(S),!,
  7240.          nl,nl,print('TRANSFERS'),nl,nl,print('---------'),nl,nl,q(0,S).
  7241.  
  7242.  
  7243.  
  7244. /*  Wordck checks for the end of the set, [], then if the word is in the
  7245. vocabulary.  If not, it asks for the catagory, and adds it to the file
  7246. WORD.TEM which is joined with the program after it has run.*/
  7247.  
  7248.  
  7249.  
  7250.  
  7251.  
  7252. wordck([])   :-   !,true.
  7253.  
  7254. wordck([H|T]) :- word(H,Y),wordck(T).
  7255.  
  7256.  
  7257. wordck([H|T]) :-  nl,print(H,' is not a recognized word '),
  7258.                   nl,print(' enter verb,aux, .. '),read(Z),
  7259.                   wordnew(H,Z),wordck(T).
  7260.  
  7261. wordnew(W,Z) :- assertz(word(W,Z)),open('word.tem',ar),
  7262.                 nlf('word.tem'),
  7263.                 printf('word.tem', 'word(', W, ',', Z, ').'),
  7264.                 close('word.tem').
  7265.  
  7266.  
  7267.  
  7268.  
  7269. /*  Trans checks the catagory of the current word (H) versus the catagory
  7270. required to make a transistion (Z).  */
  7271.  
  7272.  
  7273.  
  7274.  
  7275. trans(H,Z)   :-  word(H,X), member(X,[Z]).
  7276.  
  7277.  
  7278. qfail(Nq,S,E)  :-  !, nl,nl,print('The sentence failed at ',Nq),nl,
  7279.                  print('The sentence form to this node is ',E),nl,
  7280.                  print('The rest of the sentence is ',S),qend1.
  7281.  
  7282.  
  7283. qend(Z,E)  :-  nl,nl,print('OUTPUT'),nl,print('------'),nl,nl,
  7284.                print('The sentence is:'),nl,nl,print(E),nl,nl,
  7285.                print('The sentence is completed at node ',Z),qend1.
  7286.  
  7287.  
  7288. qend1 :- open('word.tem',ar),nlf('word.tem'),
  7289.          close('word.tem'),exec('ren atn.pro atn.sav'),
  7290.          exec('copy atn.sav+word.tem atn.pro'),
  7291.          exec('erase atn.sav'),exec('erase word.tem').
  7292.  
  7293.  
  7294. /*    Print transfer from node to node */
  7295.  
  7296.  
  7297.  
  7298. qout(A,B,C,D,E,F) :- append(E,[C,'(',A,')'],F),
  7299.                      nl, print('Transfer from node ',B,' to node ',D,
  7300.                      ' by word ',A,' evaluated as a ',C).
  7301.  
  7302.  
  7303.  
  7304.  
  7305. /*   Main program to check the conditions for transfer from node to node.
  7306.      The first number is the number of the node, i.e. q(0.. is node 0.
  7307.      The module either checks for a word type and transfers control
  7308.      directly, or passes to np / pp the next node.                    */
  7309.  
  7310.  
  7311. /*  Node 0 - aux to 4 / np to 1 / or fail          */
  7312.  
  7313.  
  7314. q(0,[H|T])  :-  trans(H,[aux]),!,qout(H,0,[aux],4,E,F), q(4,T,F).
  7315.  
  7316. q(0,[H|T])  :-  np(H,T,1,[],0,[np]).
  7317.  
  7318. q(0,S)      :-  qfail(0,S,[]).
  7319.  
  7320.  
  7321.  
  7322.  
  7323. /*  Node 1 - verb to 2 / aux to 5 / or fail    */
  7324.  
  7325.  
  7326.  
  7327. q(1,[H|T],E)  :-  trans(H,[verb]),!,qout(H,1,[verb],2,E,F), q(2,T,F).
  7328.  
  7329. q(1,[H|T],E)  :-  trans(H,[aux]),!, qout(H,1,[aux],5,E,F), q(5,T,F).
  7330.  
  7331. q(1,S,E)      :-  qfail(1,S,E).
  7332.  
  7333.  
  7334.  
  7335.  
  7336. /*  Node 2 -  null to end / np to 2 / pp to 3 / or fail     */
  7337.  
  7338.  
  7339.  
  7340. q(2,H,E)      :- member(H,[[]]), !,
  7341.                    qend(2,E).
  7342.  
  7343. q(2,[H|T],E)  :-  np(H,T,2,E,2,[np]).
  7344.  
  7345.  
  7346. q(2,[H|T],E)  :-  pp(H,T,3,E,2,[pp]).
  7347.  
  7348. q(2,S,E)      :-  qfail(2,S,E).
  7349.  
  7350.  
  7351.  
  7352.  
  7353. /*  Node 3 - null to end / or fail         */
  7354.  
  7355.  
  7356. q(3,H,E)  :-
  7357.                trans(H,[]), !,
  7358.                qend(3,E).
  7359.  
  7360. q(3,S,E)      :-  qfail(3,S,E).
  7361.  
  7362.  
  7363.  
  7364.  
  7365.  
  7366. /*  Node 4 - np to 5 / or fail           */
  7367.  
  7368.  
  7369.  
  7370.  
  7371. q(4,[H|T],E)  :-  np(H,T,5,E,4,[np]).
  7372.  
  7373. q(4,S,E)      :-  qfail(4,S,E).
  7374.  
  7375.  
  7376.  
  7377. /*  Node 5 - verb to 2 / or fail         */
  7378.  
  7379.  
  7380. q(5,[H|T],E)  :-  trans(H,[verb]),!, qout(H,5,[verb],2,E,F), q(2,T,F).
  7381.  
  7382. q(5,S,E)      :-  qfail(5,S,E).
  7383.  
  7384.  
  7385.  
  7386.  
  7387. /*  Noun phrase -  (det) (adj) (adj) .. noun        */
  7388.  
  7389. /*  The np1 clause is required to allow recursive calls for adj   */
  7390.  
  7391.  
  7392.  
  7393. np(H,[S|T],Nq,E,Lq,G)  :-  trans(H,[det]), !,
  7394.                            append(G,['det(',H,')'],G1),
  7395.                            np1([S|T],Nq,E,Lq,G1).
  7396.  
  7397.  
  7398. np(H,Z,Nq,E,Lq,G)      :-  np1([H|Z],Nq,E,Lq,G).
  7399.  
  7400.  
  7401.  
  7402. np1([H|T],Nq,E,Lq,G)  :-  trans(H,[adj]),
  7403.                           append(G,['adj(',H,')'],G1),
  7404.                           np1(T,Nq,E,Lq,G1).
  7405.  
  7406.  
  7407. np1([H|T],Nq,E,Lq,G)  :-
  7408.                           trans(H,[noun]),!,nl,
  7409.                           append(G,['noun(',H,')'],G1),
  7410.                           append(E,G1,F),
  7411.                           print('Transfer from node ',Lq,' to ',Nq),
  7412.                           print(' by ',G1),q(Nq,T,F).
  7413.  
  7414.  
  7415.  
  7416.  
  7417. /*  Prep phrase requires a prep followed by a np   */
  7418.  
  7419.  
  7420.  
  7421.  
  7422. pp(H,[S|T],Nq,E,Lq,G)  :-  trans(H,[prep]),
  7423.                            append(['prep(',H,')'],G,G1),
  7424.                            np(S,T,Nq,E,Lq,G1).
  7425.  
  7426.  
  7427.  
  7428.  
  7429.  
  7430. /*   Word defines the vocabulary set                  */
  7431.  
  7432.  
  7433. word(the,[det]).
  7434. word(boy,[noun]).
  7435. word(runs,[verb]).
  7436. word(happy,[adj]).
  7437. word(john,[noun]).
  7438. word(can,[aux]).
  7439. word(run,[verb]).
  7440. word(a,[det]).
  7441. word(big,[adj]).
  7442. word(small,[adj]).
  7443. word(girl,[noun]).
  7444. word(dog,[noun]).
  7445. word(on,[prep]).
  7446. word(pretty,[adj]).
  7447. word(fast,[adj]).
  7448. word(barks,[verb]).
  7449. word(to,[prep]).
  7450. word([],[]).
  7451.  
  7452. word(giant, [noun]).
  7453. word(is, [verb]).
  7454.  
  7455. word(giant, [noun]).
  7456. word(is, [verb]).
  7457. word(sleeps, [verb]).
  7458.  
  7459. word(mary, [noun]).
  7460. word(likes, [verb]).
  7461.  
  7462.  
  7463.  
  7464.  
  7465. word(fly, [verb]).
  7466.  
  7467.  
  7468. word(rides, [verb]).
  7469. word(large, [adj]).
  7470. word(bike, [noun]).
  7471. word(store, [noun]).
  7472.  
  7473.  
  7474.  
  7475. word(gull, [noun]).
  7476. word(green, [adj]).
  7477.  
  7478. word(plane, [noun]).
  7479. word(silver, [adj]).