[net.sources] pdprolog.1

fiore@hope.UUCP (David Fiore) (11/08/86)

This is the documentation to PD PROLOG.  The next file contains
the uuencoded program.  Cut on the dotted line and print out the
resulting file.

================================Cut Here=================================


         
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
                     A.D.A PROLOG Documentation Version 1.5
                  for the Educational and Public Domain Versions
        
                                  June 23, 1985
        
              Copyright Robert Morein and Automata Design Associates
        
                                 1570 Arran Way
                               Dresher, Pa. 19025
        
                                 (215)-646-4894
        
        
        
        

























        
        
        
             The  public domain PD PROLOG system has been contributed  to 
        the  public domain for unrestricted use with one  exception:  the 
        object  code  may not be  disassembled  or  modified.  Electronic 
        bulletin  boards  and SIG groups are urged to aid in giving  this 
        software the widest possible distribution.
        
             This documentation may be reproduced freely,  but it may not 
        be  included in any other documentation without the permission of 
        the author.
        
         




















































        	
             We  are  pleased to present the second major version  of  PD 
        PROLOG, version 1.5. The memory requirements are somewhat greater 
        than the original,  since it is uses the large memory  model.  It 
        compensates in thoroughness. The memory requirement is about 200K 
        bytes  of  TPA,  and it will benefit from up to 240k  bytes.  The 
        availalble workspace is 100K bytes.
        
        
        We  hope  that you'll get some fun out of this  PROLOG.  It  will 
        afford  you exposure to THE fifth generation language at the cost 
        only  of  some  intellectual  effort.  The  motive  is  perfectly 
        explicable:  We  want you to think of Automata Design  Associates 
        for  fifth  generation  software.  It also gives us a  nice  warm 
        feeling.
             The  memory requirement is 200 k of transient program  area, 
        plus  whatever  space is needed to execute programs  from  within 
        PROLOG.  DOS  or  MSDOS 2.0 are required.  There are no  features 
        requiring IBM PC architecture.















































        
             Automata  Design  Associates  specializes  in  software  for 
        artificial  intelligence  and  robotic  applications.   A  PROLOG 
        language  system is available in various configurations.  A  LISP  
        interpreter will be introduced in March of 1985.
        
        
             There  are five versions of PROLOG available  from  Automata 
        Design  Associates.  All  of  them run under the MSDOS  or  PCDOS 
        operating systems. Other environments will be supported soon.
        
        
             .Public Domain PROLOG
        
        This  serves to further the general awareness of the public about 
        PROLOG.  It  also is an excellent adjunct to anyone learning  the 
        language.  Most  of  the core PROLOG described  by  Clocksin  and 
        Mellish  in the book Programming In PROLOG is implemented.  Trace 
        predicates  and  I/O  redirection  are  not.   
        
        
             .Educational PROLOG
        
        At  extremely modest cost this affords an educational institution 
        or  individual  a  PROLOG  system  which  provides  the   maximum 
        available  programming  area  available  within  the  8086  small 
        programming model.  Tracing,  a debugging aid,  allows monitoring 
        a program as it runs.  User settable spy points selectively allow 
        this.  Exhaustive  tracing  is also  available.  I/O  redirection 
        gives some file ability.
        
             An  "exec"  function allows the execution of  a  program  or 
        editor  from  within  PROLOG,  thus  encouraging  an  interactive 
        environment.
        
             Definite clause grammar support is now included.
             
             The cost of Educational PROLOG is $29.95.




























        
             .FSM PROLOG
        
             A  small  increment  in price adds full random  access  file 
        capability. Character and structure I/O are allowed.
             The  "asserta and "assertz" predicates are expanded and work 
        with a clause indexing ability.  One can assert clauses  anywhere 
        in the database under precise pattern matching control. 
        
             A tree structured lexical scoping system and floating  point 
        arithmetic are other enhancements.
        
             The cost of FSM PROLOG is $49.95
        
        
        
             .VMI PROLOG -- Virtual Memory (Replaces type VMS)
        
        
             At reasonable cost the addition of virtual memory gives  an 
        expansion of capabilities of an order of magnitude. 
        
             The  database on disk is treated transparently.  No  special 
        provisions  need  be  made  by the  user.  Virtual  and  resident 
        databases  may be mixed.  A unique updating algorithim  preserves 
        the format of the database as typed by the user while making only 
        those changes necessary to make it equivalent to the database  in 
        central memory.
        
             The cost of VMI PROLOG is $99.95
        



































        
             A.D.A.  PROLOG is a remarkable fifth generation developement 
        tool  for  the  implementation  of  intelligent  strategies   and 
        optimized  control.  It  is both the kernel for  applications  of 
        virtually  unlimited scope and a sophisticated developement  tool 
        that multiplies the productivity of the programmer many times. 
        
             With  a  cost/performance ratio exceeding that of any  other 
        product  and  a  compatibility  insured  by  compliance  to   the 
        Edinburgh syntax, performance is enhanced by numerous extensions, 
        many of them invisible to the user.
        
             A quick overview of some of the features discloses:
        
             1) Invisible compilation to a semantic network preserves the 
             flexibility  of  the  interpreted mode and the  speed  of  a 
             compiler.
                  The programmer can compile and recompile any portion of 
             a  module at any time.  The edit/compile/test cycle is short 
             and free of strain. An interface is provided to an editor of 
             choice.
        
             2) Floating point arithmetic with a full complement of input 
             and output methods, transcendental and conversion functions.
        
             3)  Virtual memory.  Module size and number is unrestricted. 
             Resident and virtual modules may be coresident.  Compilation 
             is incremental. The cache algorithim is sophisticated.
                  Changes  made in the database can be updated to disk by 
             a single command.
        
             4) A powerful exec function,  and acceptance of stream input 
             make integration into applications practical.
        
             5) Many   additional  built-in  predicates   enhance   the 
             efficiency of the system.
        
             6) Debugging facilities let you see your program run without 
             any additional generation steps.
        
             7)  Totally  invisible and incremental  garbage  collection. 
             There is NEVER any wait for this function.
        
        The  cost  of this system is $200 for the MSDOS version.
        
        




















        
             Half  the  cost  of any A.D.A.  PROLOG  interpreter  may  be 
        credited to the purchase of a higher level version.
             The  full cost of VMS prolog may be applied to the  purchase 
        of VMI or VML PROLOG.
             Updates  to  a particular level product vary from $15.00  to 
        $35.00.
        
        
                                Run-time Packages
        
             Software  developers wishing to integrate an A.D.A.  product 
        into  their  system  should inquire  about  specialized  run-time 
        packages available at reasonable cost.
        
        
        
                              Technical Information
        
             Technical information may be obtained at (215) - 646- 4894
        
             Perhaps we can answer the following questions in advance:
        
             There is no support for:  APPLE II, Atari, Commodore, or  
        CPM 80 .  Other machines from these manufactures may be supported 
        in the future.
        
             The   public   domain   version  is   available   from   the 
        organizations  who distribute such software.  It is not available 
        from us.
             The MSDOS products are available on 5" and 8" diskettes.
             
        
        
        
                              To Place Your Order:
        
             You may place your order at either of the following numbers:
        
             (215)-646-4894   - day and night.
        
             (215)-355-5400   - 9 A.M. to 5 P.M., Eastern Standard Time
        
             Resellers should call (215)-646-4894 for information.
        
        
                                     Returns
        
             The  software may be returned within 30 days of purchase for 
        a full refund.  This applies whether or not the software has been 
        used.  We do ask that manuals, disks and packaging be returned in 
        excellent condition.














                        without Knowing What You're Doing
        
             We strongly advise that you purchase the book Programming in 
        PROLOG by Clocksin and Mellish,  publisher Springer Verlag, 1981. 
        For  the  impatient we give some advice.  Type the  demonstration 
        program you wish to run.  There must be at least one entry  point 
        within  the  program.  
        
        Note:  Please  understand that these are demonstrations programs. 
        Regarding  user  interface,  they are poorly  written.  You  will 
        probably have to read Clocksin and Mellish to appreciate that the 
        following examples of input are not equivalent: "yes." , "yes" .
        
        
        The animals program - "animal"
         
             Most  of the examples require C & M for  comprehension.  The 
        program "animals", however, can be appreciated by anyone. It is a 
        traditional   example of an expert system.
             
             We had hoped to include the animals program on disk,  but we 
        have  found  to  our  dismay that the version which  we  used  is 
        allegedly copyrighted by the implementors of PROLOG 86.  Don't be 
        surprised - even "happy birthday" is copyrighted.  We will simply 
        point out that the November '84 issue of Robotics Age included  a 
        version  of  the  animals game,  which you can,  at the  risk  of 
        copyright infringement,  type in.  There is only one change  that 
        need  be  made.  The "concat" function used in that  program  has 
        arguments of the form:
        
                      concat( [atom1, atom2,...], result ).
        
        In order to make the concat definition more closely resemble that 
        of  "name",  which  is  described by Clocksin  and  Mellish,  the 
        argments have been reversed:
        
                      concat( result, [atom1, atom2,...] )
        
        Assuming  that you have typed in the program and made the  change 
        just noted, the following steps are required to run it:
             
             Run the prolog.exe file.  The prompt "?-" will appear.  Type 
        "consult( 'animals' ).<CR>".  Here <CR> indicates you are to type 
        a  carriage  return.  The PROLOG system will load  "animals"  and 
        compile  it into an internal form.  When the "?-" prompt  appears 
        PROLOG is ready to run the "animals" guessing game. The object of 
        the program is to deduce the animal you are thinking of. To start 
        it  off  type  "help.<CR>".  PROLOG  will  respond  by  asking  a 
        question. 
             Because of the way the animals program is written,  you must 
        respond in a rigid format.  You may type "yes<CR>",  "no<CR>", or 
        "why<CR>". 
             Eventually the program will terminate with either a guess as 
        to what animal you are thinking of,  or a remark that the  animal 
is  not within its domain of knowledge.  The program has learned0&a
        , 
        however.  You  may  run  the  program again to  see  what  effect 
        additional knowledge has on the program's behavior. 








        
             The program fragment "console" shows how you may improve the 
        console input routines of any of these programs.
             
        
        The Hematology Diagnosis Program - "hemat"
        
             Although  the  logical structure is not as sophisticated  as 
        that of "animals", it is interesting for several reasons:
        
             1)  The  program  evaluates numerical data to  arrive  at  a 
        diagnosis.
        
             2) Although inaccurate, it demonstrates that useful question 
        answering systems are not difficult to write in PROLOG.
        
             3)  There  are  some mistakes in  the  program,  which  only 
        slightly impede its usefulness. 
        
             This  program  uses  structure  input.  Terminate  all  your 
        answers with a period, as in "y.<CR>", or "no.<CR>".
        The starting point is "signs.<CR>".  PROLOG will prompt  you 
        for  signs  of  anemia.  The  program attempts  to  diagnose  two 
        varieties of a hemolytic anemia.
             The program could use a good working over by a  hematologist 
        and we would be delighted to collaborate.
        
        
        Prime Number Generator - "sieve"
        
             This  program demonstrates that anything can be programed in 
        PROLOG if one tries hard enough.  Asking the  question   
          "primes( 50, L ).<CR>" causes a list of prime numbers less than 
        50  to be printed out.  "Sieve" is heavily recursive and  quickly 
        exhausts the stack space of the small model interpreters.
        
        
        Grrules
        
             This  is  an  example  of the use  of  the  definite  clause 
        grammer  notation.  PD  PROLOG  does not  have  this  translation 
        facility,  but ED PROLOG and  all of our other versions do. It is 
        possible  to  perform  the  translations  by  hand  if  you  have 
        thoroughly  read  C  & M.  Then you would have  the  pleasure  of 
        asking:
        
                 ?-sentence( X, [every,man,loves,a,woman], [] ).
        
        and  having the meaning elucidated as a statment in the predicate 
        calculus.
















        
             For  some  inexplicable reason,  demonstration programs  are 
        hard to come by. We are too busy writing PROLOG fill this gap. We 
        will  reward the contribution of "cute" sample programs with  the 
        following:
        
             1) A free  copy of type VMS virtual memory PROLOG
        
             2) The sample program will be published as an intact file 
             together with whatever comments or advertisments the author
             may see fit to include, on our distribution disks. 
        
             3) Exceptional contributions may merit a copy of type VML 
             large  model virtual memory PROLOG which now incorporates  a 
             UNIX1 style tree structured domain system.
        
        
                                Special Offer # 2
        
        
             If  you are a hardware manufacturer and would like a  PROLOG 
        language  for your system,  the solution is simple.  Just send us 
        one  of  your machines!  Provided your system  implements  a  "C" 
        compiler, it will be ported in no time flat.
        
        
        ______
             1. Trademark of AT & T.
        





































        
             You do not type in programs at the "?-" prompt.  There is no 
        built-in  editor.  The command "consult( user )" is accepted  but 
        does not cause PROLOG to enter an editing mode.  We feel that the 
        most universally acceptable editing method is for the user to use 
        a text editor of choice,  which can be invoked from within PROLOG 
        by the "exec" predicate.
        
             Use  Wordstar  or your customary editor to write a  program. 
        Then  run  PD  PROLOG and use the consult function  to  load  the 
        program.
        
             In  all  cases except PD PROLOG,  you can  run  your  editor 
        without leaving PROLOG by use of the "exec" predicate.
        
        
        
                             Running the Interpreter
        
        COMMANDS: Give commands in lower case.
        
        TO RUN:
             Invoke PROLOG.EXE. After the "?-" prompt appears,
               type "consult( <filename><CR> )", where <filename> is the 
               desired database.
             To exit, type "exitsys.<CR>"
        
        TO ASK A QUESTION:
             At the prompt, type "<expression>.<CR>", where 
             <expression>  is  a  question as described by  Clocksin  and 
             Mellish. Be sure to terminate the question with a period.
             The question may be up to 500 characters long.
        
        TO INPUT A STRUCTURE AT THE KEYBOARD:
             The structure may be up to 500 characters in length. Be sure 
             to terminate with a period.
        
        TO ASK FOR ANOTHER SOLUTION:
             If a solution has been provided, the PROLOG interpreter will 
             ask  "More?  (Y/N):".  Only  if  a "y"  is  typed  will  the 
             interpreter perform a search.
        
        TO ABORT A SEARCH:
             Simply   type   the  escape  key.   The   interpreter   will      
             respond  with  "Interrrupted.",  and return to  the  command      
             prompt.
        
        TO LOAD ANOTHER DATABASE:
             Type  "consult(<filename>).<CR>" The file name must have the 
             extension  ".PRO".  It  is  not  necessary  to  include  the 
             extension in the argument of consult.
        
        TO REMOVE A DATABASE:
             Type "forget(<filename>).<CR>"

        TO EXIT TO THE OPERATING SYSTEM:
             Type "exitsys.<CR>"
        








             The system is totally interactive; any commands the operator 
        gives  are and must be valid program statements.  Statements must 
        terminate with a period.      All commands which take a file name 
        also  accept a path name.  Any name which is not a  valid  PROLOG 
        atom (refer to C & M) must be enclosed in single quotes. Thus one 
        could say
        
             consult( expert )
        
        but one would need single quotes with
        
             consult( 'b:\samples\subtype\expert' ).
        
        
        To exit the system, type "exitsys.<CR>"
        
        Atoms  may contain MSDOS pathnames if they are enclosed by single 
        quotes, ie.,  '\b:\samples\animal' .
        
        You may consult more than one file at a time.  However, all names 
        are public and name conflicts must be avoided. The order in which 
        modules are loaded may,  in cases of poor program design,  affect 
        the behavior.
        
        
        
        
                             Command Line Arguments
        
             ED  PROLOG accepts one command line argument,  which is  the 
        name  of  a "stream" which replaces the console  for  input.  The 
        "stream"  in  MSDOS is a pipe or file which supplies input  until 
        end-of-file is reached. Control then reverts back to the console. 
        To avoid noisy parser error messages when end-of-file is reached, 
        the last command in the file should be "see( user )."
        
        
        
                               A Reference of Note
        
        
             With  minor  exceptions,  the syntax is a superset  of  that 
        described  by  Clocksin and Mellish in the  book  Programming  in 
        Prolog by W.F.  Clocksin and C.S.  Mellish, published by Springer 
        Verlag in Berlin, Heidelberg, New York, and Tokyo. We shall refer 
        to this book as "C & M".
        
        
             There   are  very  few   syntactical   differences,   mostly 
        unrecognized and/or minor.
             When  an operator is declared using the "op" statement,  the 
operator must be enclosed in single quotes in the "op"  statemen0&a
        t 
        itself,  if  it would not otherwise be a legal Edinburgh functor. 
        Subsequently,  however,  the parser will recognize it for what it 
        is,  except  in  the "unop" statement,  where it  must  again  be 
        enclosed in single quotes.
        








             Variable numbers of functor paramaters are supported.
        
             A  goal  may be represented by a  variable,  which  is  less 
        restrictive  than  the  C  &  M requirement  that  all  goals  be 
        functors.  The  variable must be instantiated to a  functor  when 
        that goal is pursued.
        
             Rules which appear inside other expressions must be enclosed 
        in  parenthesis  if  the "," operator is to be  recognized  as  a 
        logical connective.
        
             All  infix  operators described by C & M,  and user  defined 
        infix,  prefix, and postfix operators with variable associativity 
        and precedence are supported exactly as in C & M.
        
        
        
        
















































        
        
             The  following built in predicates described by Clocksin and 
        Mellish   are  supported.   Those  marked  with  asterisks   have 
        additional features:
             
             arg
             arithmetic operators:  "+", "-", "*", "/", <, <=, >, >=, mod
            *asserta
            *assertz
             atom
             atomic
             call
            *clause
             clearops
             consult
             !
            *debugging
            *display
             fail
             functor
            *get0
             integer
             is
             list extraction operator: "|"
             listing
             logical connectives:  ",", ";",
             mod
             name
             nl
             nodebug
             nonvar
             not
             notrace
             op
            *put
            *read
            *reconsult
             repeat
             retract
             see
             seeing
             seen
             spy
             tab
             tell
             telling
             told
             trace
             true
             var















        
                        Description of the Modifications.
             
        
        call( <goal> )
        
             The  predicate as defined in C & M is obsolete.  The purpose 
        was  to permit a goal search where the goal name was  a  variable 
        instantiated  to  some functor name.  A.D.A.  permits writing  of 
        goals with such names,  so the mediation of the "call" clause  is 
        no longer necessary.
        
             The  "call"  predicate  may  be  trivially  implemented  for 
        compatibility with the PROLOG definition
        
                                 call( X ) :- X.
        
        
        
        clause
        
             The  function  clause(  X,  Y ) has the  new  optional  form 
        clause(  X,  Y,  I  ).  If the third variable is written,  it  is 
        instantiated  to the current address of a clause in  memory.  The 
        only  use of the result is with succeeding assertfa and  assertfz 
        statements.
        
        
        
        cut
             If  the cut is the last clause of a search the user will not 
        be queried "More? Y/N" for additional solutions.
        
        
        
        debugging
        
             "Debugging"  prints a list of the current  spypoints.  After 
        each name a sequence of numbers may appear, indicating the number 
        of  arguments that is a condition of the trace.  The  word  "all" 
        appears  if  the  number of arguments is not a condition  of  the 
        trace.
























        
             Defines  the  user  definable  grammar  of  a  functor.  The 
        definition conforms to that in C & M. We mention here a minor but 
        important point.  If <functor> is not a valid PROLOG atom it must 
        be   enclosed  in  single  quotes  when  declared  in  the   "op" 
        declaration and when undeclared in the "unop" declaration.  It is 
        not  necessary  or legal to do this when the functor is  actually 
        being used as an operator.
        
             Declared  operators  are annotated in the directory  display 
        with their precedence and associativity.
        
        
        Output predicates
        
           display
           write
           print
           put
        
             These  functions  have  been  modified  to  accept  multiple 
        arguments in the form:
        
                       print( <arg1>, <arg2>, <arg3>,... )
        
        Thus, "put( a, b, c )" would result in the display of "abc".
             The  names  of  some  PROLOG atoms that may  occur  are  not 
        accepted  by  the  PROLOG scanner  unless  surrounded  by  single 
        quotes.  This only applies when such an atom is read in, not when 
        it is internally generated. Nevertheless, this presents us with a 
        problem:  We  would  like to be capable of writing  valid  PROLOG 
        terms to a file. In some cases, it is necessary to add the single 
        quotes.  In other cases,  such as human oriented output, they are 
        an irritant. The modified definitions of the following predicates 
        are an attempt at a solution:
        
             display
             Operator  precedence  is ignored,  all functors are  printed 
             prefix and single quotes are printed if needed or they  were 
             supplied if and when the atom was originally input.
        
             write
             Operator  precedence is taken into account and operators are 
             printed according to precedence.  Single quotes are  printed 
             under the same conditions as for "display."
        
             print
             Operator  precedence is taken into account and operators are 
             printed  according to precedence.  Single quotes  are  never 
             displayed.  This  is  a  human oriented form of  output  and 
             should  never  be used for writing of terms for  the  PROLOG 
             scanner.
        
             












        read
        
             The  functions  "get0"  and "read"  have  been  extended  to 
        support input from a stream other than the one currently selected 
        by "see". To direct output to a file or other stream, an optional 
        argument  is used.  For example,  "get0( char,  <file name> )" or 
        "get0( char,  user )" would cause input to come from <file  name> 
        or the console.  If the file has not already been opened,  "get0" 
        will fail.
        
        
        
             Atoms enclosed by single quotest, eg. '\nthis is a new line' 
        can contain the escape sequences
        
             '\n', '\r', '\t' and '\''.
        
             If these atoms are printed by "display" or "write" they  are 
        printed  just  as they are.  If they are printed by  the  "print" 
        clause they are translated as follows:
        
        '\n'  results  in  the printing of a carriage return and  a  line 
        feed.
        '\r' results in the printing of a carriage return only.
        '\t' results in the printing of a tab character.
        '\'' allows the printing of a single quote within a quoted atom.
        
             The "portray" feature is not presently implemented.
         
                        Description of the New Predicates
        
        
        clearops-
             Nullify  the  operator  status  of  every  operator  in  the 
             database.
        
        concat( (<variable> | <functor>), <List> )
             A  list  of functors or operators is concatenated  into  one 
        string,  which becomes the name of a new atom to which <variable> 
        or <functor> must match or be instantiated.
        
        
        dir( option )
             Provide  an  alphabetized listing to the console  of  atoms, 
        constants,   or   open  files.   Without  options,   simply  type 
        "dir.<CR>". Options are:
        
             dir( pred ) - list clause names only.
             dir( files ) - list open files only.
        
        
        exitsys
             Exit to the operating system.
        
forget( <file name> )
             Make  a database unavailable for use and reclaim the storage 
        it occupied.
        








        
        ratom( <arg>, <stream> )-
             Read an atom from the input stream,  to which <arg>  matches 
        or  is  instantiated.  <stream> is optional.  If <stream> is  not 
        given, the input stream defaults to the standar input.
             Input is terminated by a CR or LF, which are not included in 
        the stream.
        


























































        
             Integer  arithmetic is supported.  Numbers are 32 bit signed 
        quantities. The following arithmetic operators are supported:
        
                      "+", "-", "*", "/", <, <=, >, >=, mod.
        
        Arithmetic operators must never be used as goals,  although  they 
        may be part of structures. It is legal to write:
        
                                    X = a + b
             
        which  results in the instantiation of X to the struture (a + b). 
        But the following is not legal:
        
                       alpha( X, Y ) :- X + Y, beta( Y ).
        
        
        Evaluation  of  an arithemtic expression is mediated by the  "is" 
        and inequality predicates.  For instance,  the following would be 
        correct:
        
                         alpha( X, Y, Z ) :- Z is X + Y.
        
                         beta( X, Y ) :- X + 2 < Y + 3.
        









































        
        
                                  Introduction
        
        
        
        
             Probably  you  have heard of the language PROLOG within  the 
        last year or so. You probably wondered the following things:
        
        1) What does the name stand for? Names of computer languages are 
        almost always acronyms.
        
        2) What is it good for?
        
        3) Why now?
        
        4) Can I get a copy to play with?
        
             Congratulations! You obviously know the answer to the fourth 
        question. We now respond to the other three.
             
        1)  The  name  stands for "programming in logic." This  we  shall 
        elaborate on in depth later on.
        
        2) PROLOG is good for writing question answering systems.  It  is 
        also   good   for  writing  programs  that  perform   complicated 
        strategies  that  compute the best or worst way to  accomplish  a 
        task, or avoid an undesirable result.
        
        3) PROLOG was virtually unknown in this country until researchers 
        in  Japan announced that it was to be the core language  of  that 
        country's fifth generation computer project.  This is the project 
        with  which  Japan hopes to achieve a domainant position  in  the 
        world information industry of the 1990's. 
        
             PROLOG  is  one of the most unusual computer languages  ever 
        invented.  It  cannot be compared to  FORTRAN,  PASCAL,  "C",  or 
        BASIC.  The facilities complement,  rather than replace those  of 
        conventional  languages.  Although  it  has great  potential  for 
        database  work,  it  has  nothing in  common  with  the  database 
        languages used on microcomputers.
        
             Perhaps  the  best point to make is that while  conventional 
        languages are prescriptive, PROLOG is descriptive. A statement in 
        a conventional language might read:
        
             if( car_wheels = TRUE ) then
               begin
                 (some sort of procedure)
                 X = X + 1;
               end 














        and wheels. There are many relationships that hold. For instance,
        
             has( car, wheels ).
        
             has( car, quant(wheels, four) ).
        
             round( wheels ).
        
        Each  of  these statments is an independent fact  relating  cars, 
        wheels,  and  the  characteristics of wheels.  Because  they  are 
        independent, they can be put into a PROLOG program by programmers 
        working separately. The man who is a specialist on car bodies can 
        say  his thing,  the wheel specialist can have his say,  and  the 
        participants can work with relative independence. And this brings 
        to light a major advantage of PROLOG:
        
        
                             PARALLEL PROGRAMMING!!!
                            
        
        With  conventional  programming languages projects can  still  be 
        "chunked",  or  divided between programmers.  But efficiency on a 
        team  project  drops  drastically below that  of  the  individual 
        programmer  wrapped  up  in  his own trance.  As  the  number  of 
        participants    grows   the   need   for   communication    grows 
        geometrically. The time spent communicating can exceed that spent 
        programming! 
             Although   PROLOG   does   not  eliminate   the   need   for 
        task  coordination,  the problem is considerably  simplified.  It 
        also provides the ability to answer questions in a "ready to  eat 
        form."  Consider your favorite BASIC interpreter.  Based upon the 
        statements about cars and wheels previously given,  could you ask 
        it the following question?   
        
                       
              has( car, X ), round( X ).
        
             Does  a  car  have anything which  is  round?  The  question 
        instructs the PROLOG interpreter to consider all the objects that 
        it  knows are possessed by a car and find those which are  round. 
        Perhaps  you are beginning to guess that PROLOG has the abilities 
        of a smart database searcher.  It can not only find the facts but 
        selectively find them and interpret them.























        abbreviated one:
        
        
        
        {Car won't start}
             | 
             | 
        [Engine  turns  over](No) --> [Battery voltage](no)-\
                (Yes)                                       v
                 |                                  {Check battery}
                 |
        [Smell gasoline](yes) --> {Try full throttle cranking}
                 |                       (failure)
        /--------/                           |
        
                            (details omitted)
        
        
        
             The fault tree is easily programmed in BASIC. Later we shall 
        show  that  PROLOG supplies a superior replacement for the  fault 
        tree.  Though the tree is capable of diagnosing only the  problem 
        for  which  it was designed,  PROLOG dynamically  constructs  the 
        appropriate  tree from facts and rules you have provided.  PROLOG 
        is not limited to answering one specific question.  Given  enough 
        information,  it  will attempt to find all deductive solutions to 
        any problem.
        






































                                  PROLOG PRIMER
        
        I.                       Rules and Facts     
        
        
        
             This  is  where you should start if you know  nothing  about 
        PROLOG. Let us consider a simple statment in PROLOG, such as:
        
        1)   has( car, wheels ).
        
        This  statement  is a "fact.  The word "has" in this statment  is 
        known  either  as a functor or predicate.  It is a name  for  the 
        relationship  within the parenthesis.  It implies that a car  has 
        wheels.  But  the  order  of  the words  inside  the  bracket  is 
        arbitrary and established by you. You could just as easily say:
        
        2)   has( wheels, car ).
        
        and if you wrote this way consistently,  all would be  well.  The 
        words  has,  wheels,  and car are all PROLOG atoms.  "Wheels" and 
        "car" are constants. 
             
        A   database   of  facts  can  illustrate  the   data   retrieval 
        capabilities of PROLOG. For instance:
        
        3)   has( car, wheels ).
             has( car, frame ).
             has( car, windshield ).
             has( car, engine ).
        
        You could then ask PROLOG the question:
        
        4)   has( car, Part ).
        
        The  capital  "P" of Part means that Part is a  variable.  PROLOG 
        will make Part equal to whatever constant is required to make the 
        question match one of the facts in the database. Thus PROLOG will 
        respond:
        
             Part = wheels.
             
             More?(Y/N):
        
        If you type "y" the next answer will appear:
        
             Part = frame.
        
             More?(Y/N):
        
        If you continue, PROLOG will produce the answers Part = windshield 
        and Part = engine. Finally, you will see:
        
             More?(Y/N):y

             No.
         
        indicating that PROLOG has exhausted the database.  Incidentally, 








        when  a  variable is set equal to a constant or  other  variable, 
        it is said to be instantiated to that object.
        
             Notice  that  PROLOG searches the database forwards  and  in 
        this case,  from the beginning.  The forward search path is built 
        into PROLOG and cannot be changed. An author of a program written 
        in  a  prescriptive language is quite conscious of the  order  of 
        execution  of  his program,  while in PROLOG it is  not  directly 
        under his control.
             
             The other major element is the rule which is a fact which is 
        conditionally true. In logic this is called a Horn clause: 
        
        
        5)   has( X, wheels ) :- iscar( X ).
        
        The  fact iscar( car ) and the above rule are equivalent to
        
        6)   has( car, wheels).
        
        The  symbol :- is the "rule sign." The expression on the left  of 
        :-is the "head" and on the right is the body.  The variable X has 
        scope  of the rule,  which means that it has meaning only  within 
        the rule.  For instance,  we could have two rules in the database 
        using identically named variables.
        
        
        7)   has( X,  transportation ) :- 
                           has( X,  car ), has( license, X ).
        
        8)   has( X, elephant ) :- istrainer( X ), hasjob( X ).
        
        The  variables  X in the two expressions are completely  distinct 
        and have nothing to do with each other.
        
        The comma between has( X, car ) and has( license, X ) means "and" 
        or logical conjuction.  The rule will not be true unless both the 
        clauses has(X, car) and has( license, X ) are true.
        
        
             On the other hand if there is a rule
             
        9)   has( license, X ) :- passedexam( X ).
        
        consider what PROLOG will do in response to the question:
        
        10)  has( harry, transportation ).
        
        (Notice  that  harry has not been capitalized because we  do  not 
        want  it  taken as a variable.  We could,  however,  say  'Harry' 
        enclosed in single quotes.)

             It  will scan the database and use (7),  in which X will  be 
        instantiated to harry. The rule generates two new questions:
        
        11)  has( harry, car ).
        
        12)  has( license, harry ).








        
        Assuming  that  harry  has  a car,  the first clause  of  (7)  is 
        satisfied and the database is scanned for a match to (12). PROLOG 
        picks  up  rule (9) in which X is instantiated to harry  and  the 
        question is now posed:
        
        13)  passedexam( harry ).
        
             If there is a fact:
        
             passedexam( harry ).
        
        in  the database then all is well and harry  has  transportation. 
        If there is not, then PROLOG will succinctly tell you:
        
             No.
        
        But  suppose Harry has money and can hire a chauffer as any  good 
        programmer  can.  That  could be made part of the program in  the 
        following way.
        
             The rule which PROLOG tried to use was:
        
        14)  has( X,  transportation ) :- 
                           has( X,  car ), has( license, X ).
        
        At any point following it there could be included another rule:
        
        15)  has( X, transportation ) :- has( X, money ).
        
        or simply the bald fact:
        
        16)  has( harry, transportation ).
        
             These  additional  rules  or  facts would  be  used  in  two 
        circumstances.  If at any point a rule does not yield a solution, 
        PROLOG   will  scan  forward  from  that  rule  to  find  another 
        applicable  one.  This process is known as "backtracking  search" 
        and can be quite time consuming.
        
        
        If  in response to the "More?" prompt you answer "y" PROLOG  will 
        search  for an additional distinct solution.  It will attempt  to 
        find an alternate rule or fact for the last rule or fact used. If 
        that  fails,  it  will back up to the antecedent rule and try  to 
        find  an alternate antecedent.  And it will continue to  back  up 
        until  it  arrives at the question you asked,  at which point  it 
        will say:

             No.
        
        "Antecedent"  to a rule means that it gave rise to its' use.  For 
        example,  (7)  is  the antecedent of (9) in the  context  of  the 
        question (16).
        
        
        
        








        II.                          Grammar
        
             It is a boring subject, but it must be discussed. All PROLOG 
        statements are composed of valid terms, possibly a rule sign (":-
        "),  commas representing conjunction ("and"), and a period at the 
        very end.
             A term is a structure, constant, variable, or number.
         
             What is a structure? It is a kind of grouping:
        
             1) Structures consist of a functor, and a set of objects or
                structures in parenthesis.
        
             2)  Objects are constants,  variables,  numbers,  or  lists, 
                which we have not discussed yet.
        
             3)  A  constant or functor must be a string of  letters  and 
                numbers, beginning with a lower case letter, unless
                you  choose  to  enclose  it in single  quotes  (  'howdy 
                pardner'  ),  in  which  case you are  freed  from  these 
                restrictions.
             4) A  variable  must be a string of  letters  and  numbers 
                beginning with a capital letter.
             
             5) A  functor  may optionally have  arguments  enclosed  in 
                parenthesis , as in: hascar( X ) or hascar. 
        
        An example:  "has( X, transportation )." is a structure.
        





































        
             You   now   know  enough  to  write  simple  databases   and 
        interrogate   them  profitably.   But  before  we  examine   more 
        sophisticated  examples,  it  will be necessary to add input  and 
        output to the language. There are built in functions which appear 
        as rules which are satisfied once. Thus the statment:
        
             write( 'Hello world.' ).
        
        can be included on the right side of a rule:
        
        
        greetings(  X ) :- ishuman( X ),  write( 'Hello world.' ).  You 
        can  also write "write( X )" where X is some variable.  Note that 
        'Hello  world.' is not enclosed in double quotes.  Single quotes, 
        which denote a constant, are required. Double quotes would denote 
        a list, which is another thing entirely.
        
        Provided  that  a match to "ishuman" can be  found,  the  builtin 
        function  "write"  is  executed and the message  printed  to  the 
        screen.
             The  builtin  read( X ) reads a "structure" that  you  input 
        from the keyboard. More formally, we have
        
             read( <variable> or <constant> )
             write( <variable> or <constant> )
        
        If you write read( Input ),  then the variable "keyboard" will be 
        assigned to whatever is typed at the keyboard,  provided that the 
        input  is a valid PROLOG structure.  The builtin "read" will fail 
        if instead of Keyboard we wrote read( baloney ),  where "baloney" 
        is a constant,  and the user at the keyboard did not type exactly 
        "baloney." 
        
        When you input a structure in response to a "read" statement,  be 
        sure to end it with a period and an <ENTER>. 
        
             There  is  a convenient way of putting the cursor on  a  new 
        line. This is the builtin "nl". For example:
        
             showme :- write( 'line 1' ), nl, write( 'line 2' ). 
        
        would result in:
        
             line 1
             line 2
        
             There  is  also a primitive form of input/output for  single 
        characters. It will be discussed later.

















        
             Consider the "won't start" fault tree for an automobile:
        
        {Car won't start}
             | 
             | 
        [Engine  turns  over](No) --> [Battery voltage](no)-\
                (Yes)                                       v
                 |                                  {Check battery}
                 |
        [Smell gasoline](yes) --> {Try full throttle cranking}
                 |                       (failure)
        /--------/                           |
        |           /------------------------/ 
        |           |                       
        |           |
        |  [Check for fuel line leaks](yes)-->{Replace fuel line}
        |          (no)
        |           |
        |           |
        |  [Check for defective carburator](yes)--\
        |          (no)                           v
        |                                {Repair carburator}
        \----\
             |
             |
        [Is spark present](no)-->[Do points open and close](no)-\
             |                             (yes)                v
        /----/                               |          {Adjust points}
        |           /------------------------/
        |           |
        |  [Pull distributor wire, observe spark](blue)--\
        |        (orange)                                v
        |           |                           {Check plug wires & cap}
        |           |
        |  [Measure voltage on coil primary](not 12V)--\
        |         (12V)                                v
        |           |              {Check wiring, ballast resistor}
        |           |
        |  [Check condenser with ohmmeter](conducts)--\
        |    (no conduction)                          v
        |           |                         {Replace condenser}
        |           |
        |  [Open and close points](voltage not 0 - 12)--\
        |   (voltage swings 0 - 12)                     v
        |           |                         {Fix primary circuit}
        |           |
        |  {Consider hidden fault, swap components]
        |
        |
        \-------{Call a tow truck!!}















        represents  a  decision point fragment of the  tree.  The  PROLOG 
        interpreter  dynamically  assembles  the tree as  it  attempts  a 
        solution. 
        
        'car wont start' :- write( 'Is the battery voltage low?' ), 
                            affirm, nl,
                            write( 'Check battery' ).
        
        'car wont start' :- write( 'Smell gasoline?' ), 
                            affirm, nl,
                            'fuel system'.
        
        'fuel system'    :- write( 'Try full throttle cranking' ).
        
        'fuel system'    :- write( 'Are there fuel line leaks?' ),
                            affirm, nl,
                            write( 'Replace fuel line.' ).
        
        'fuel system'    :- write( 'Check carburator' ).
        
        'car wont start' :- write( 'Is spark present?' ),
                            not( affirm ), nl,
                            'no spark'.
        
        'no spark'       :- write( 'Do points open and close?' ),
                            not( affirm ), nl,
                            write( 'Adjust or replace points.' ).
        
        'no spark'       :- write( 'Is the spark off the coil good?' ),
                            affirm,
                            write( 'Check plug wires and cap.' ).
        
        'no spark'       :- write( 'What is the voltage on the primary
                             of the coil: ' ), 
                            read( Volts ), 
                            Volts < 10,
                            nl,
                            write('Check wiring and ballast resistor.').
        
        'no spark'       :- write( 'Does the capacitor leak?' ),
                            affirm,
                            write( 'Replace the capacitor.' ).
        
        'no spark'       :- not( 'primary circuit' ).
        
        'primary circuit' 
                         :- write( 'Open the  points.  Voltage  across 
                              coil?:'), nl,
                            read( Openvolts ), Openvolts < 1, 
                            write(  'Close the points.  Voltage  across 
                              coil?:'),
                            read( Closevolts ), Closevolts > 10, nl,
                            write( 'Primary circuit is OK.' ). 
        
'no spark'       :- write( 'Consider a hidden fault. Swap
                              cap, rotor,points,capacitor.' ).
        
        








        'Car wont start' :- write( 'Get a tow truck!!' ).
        
        
                                 --End program--
        
        
             The  above  is  a  simple example of  an  expert  system.  A 
        sophisticated  system would tell you exactly the method by  which 
        it  has reached a conclusion.  It would communicate by a  "shell" 
        program  written  in PROLOG which would accept a wider  range  of 
        input   than  the  "valid  structure"  required  by  the   PROLOG 
        interpreter directly.






















































        
             Consider  a  shopping list given you by your wife.  It is  a 
        piece of paper with items written on it in an order that probably 
        symbolizes  their  importance.  At the top it  may  say  EGGS!!!, 
        followed by carrots, hamburger, and finally a flea collar for the 
        dog, if you can find one. In PROLOG such a list would be written:
        
        1)   [eggs, carrots, hamburger, fleacollar]
        
        The  order of a list is important so that eggs and carrots cannot 
        be reversed and PROLOG be uncaring.
        
        Let us put the list in a structure:
        
             shopping( [eggs, carrots, hamburger, fleacollar] ).
        
        Then  if you wished to isolate the head of the list you could ask 
        the question:
        
             shopping( [ Mostimportant | Rest ] ).
        
        and PROLOG would respond:
        
             Mostimportant   =  eggs,   
             Rest   =   [carrots,   hamburger, fleacollar].
        
        The vertical bar "|" is crucial here. It is the string extraction 
        operator,  which  performs  a  combination  of the  CDR  and  CAR 
        functions  of LISP.  When it appears in the context [X|Y] it  can 
        separate the head of the list from the rest, or tail.
        
        
             You  may have gained the impression that PROLOG is a  rather 
        static language capable of answering simple questions,  but it is 
        far  more powerful than that.  The string extraction operator  is 
        the  key.  It permits PROLOG to whittle a complex expression down 
        to the bare remainder.  If the rules you have given it permit  it 
        to  whittle  the  remainder  down to  nothing,  then  success  is 
        achieved. An example of this is the definition of "append."
        
             Let  us suppose you have not yet done yesterday's  shopping, 
        let alone today's. You pull it out of your wallet and sootch tape 
        it to the list your wife just gave you. Yesterday's list was:
        
             [tomatoes, onions, ketchup]
        
        Combined with [eggs, carrots, hamburger, fleacollar] we obtain
        
             [eggs,carrots,hamburger,fleacollar,tomatoes,onions,garlic].
        
        To  take one list and to attach it to the tail of another list is 
        to  "append"  the first to the second.  The PROLOG definition  of 
        append is:
        

        
        Rule1:     append( [], L, L ).
        








        Rule2:     append( [X|List1], List2, [X|List3] ) :-
                      append( List1, List2, List3 ].
        
        The  general  scheme is this:  
        
        The definition consists of one rule and one fact.  The rule  will 
        be used over and over again until what little is left matches the 
        fact.  The [] stands for empty list,  which is like a bag without 
        anything in it. This is an example of a recursive definition.
             Suppose we ask:
        
             append( [a,b,c], [d,e,f], Whatgives ).
        
        1. Rule 2 is invoked with arguments ( [a,b,c], [d,e,f], Whatgives ).
        2. Rule 2 is invoked again with arguments:
             ( [b,c], [d,e,f], List3 ).
        3. Rule 2 is invoked again with arguments:
             ( [b], [d,e,f], List3 ).
        4.  The  arguments  are now ([],  [d,e,f],  List3 ).  Rule 1  now 
            matches. End.
        
        How does this cause a list to be constructed? The key is to watch 
        the   third  argument.   Supplied  by  the  user,   it  is  named 
        "Whatgives". The inference engine matches it to [X|List3] in rule 
        2. Now lets trace this as rule two is successivly invoked: 
        
        
                Whatgives                                                
                   |                                                     
                   |                                                     
                   |                                                     
                   v                                                     
        Rule2:  [X|List3] (List3 = [b,c])                                
                 |  \                                                    
                 |   \                                                   
                 |    \                                                  
                 v     \                                                 
        Rule2:   a   [X'|List3'] (List3' = [c])                          
                      |    \                                             
                      |     \                                            
                      |      \                                           
                      v       \                                          
        Rule2:        b     [X''|List3''] (List3'' = [], ie., empty set.)
                              |    \                                     
                              |     \                                    
                              |      \                                   
        Rule1:                c       L  ( in Rule1 = [d,e,f] )              
                                                                         
        End.
        
        
L in rule 1 is [d,e,f] for the following reason: Notice that rule 
        2 never alters List2. It supplies it to whatever rule it invokes. 
        So L in rule 1 is the original List2, or [a,b,c].
        
             This example would not have worked if the order of rules one 
        and  two  were  reversed.  The  PROLOG  inference  engine  always 
        attempts to use the the first rule encountered. You could imagine 








        it as always reading your program from the top down in attempting 
        to  find an appropriate rule.  Since rule 2 would always satisfy, 
        an  unpleasant  thing  would  have happened  if  the  order  were 
        reversed. The program would loop forever.
             
        
        
        
             I  hope  that  this tiny introduction to PROLOG  whets  your 
        appetite. You should now purchase the book
        
             Programming In Prolog
             W.F. Clocksin and C.S. Mellish
             Springer - Verlag
             Berlin,Heidelberg,New York. 1981,1984
        
        


-- 
      ||
      ||         David Fiore, University of California at Riverside.
 =============
      ||         Slow mail   :  1326 Wheaton Way
      ||                        Riverside, Ca.  92507
      ||         E-Mail      
      ||            UseNet   : ...!ucdavis!ucrmath!hope!fiore
      ||            BITNET   : consult@ucrvms 
		
		Have another day!

    "...and at warp eight, we're going nowhere mighty fast"