Pilog -- PicoLisp Prolog

This sections explains some cases of using Pilog in typical application programming, in combination with persistent objects and databases. Please refer to the Pilog section of the PicoLisp Reference for the basic usage of Pilog.

Again, we use our demo application "doc/family.l" that was introduced in the Database Programming section.

Normally, Pilog is used either interactively to query the database during debugging, or in applications to generate export data and reports. In the following examples we use the interactive query front-end functions ? and select. An application will use goal and prove directly, or use convenience functions like pilog or solve.

All Pilog access to external symbols is done via the two predicates db/3 and select/3. A predicate show/1 is pre-defined for debugging purposes (a simple glue to the Lisp-level function 'show', see Browsing). Searching with db/3 for all persons having the string "Edward" in their name:
   : (? (db nm +Person "Edward" @P) (show @P))
   {2-;} (+Man)
      nm "Edward"
      ma {2-:}
      pa {2-A}
      dat 717346
      job "Prince"
    @P={2-;}
   {2-1B} (+Man)
      nm "Albert Edward"
      kids ({2-1C} {2-1D} {2-1E} {2-1F} {2-1G} {2-1H} {2-1I} {2-g} {2-a})
      job "Prince"
      mate {2-f}
      fin 680370
      dat 664554
    @P={2-1B}
   ...               # more results
To search for all persons with "Edward" in their name who are married to somebody with occupation "Queen":
   : (? (db nm +Person "Edward" @P) (val "Queen" @P mate job) (show @P))
   {2-1B} (+Man)
      mate {2-f}
      nm "Albert Edward"
      kids ({2-1C} {2-1D} {2-1E} {2-1F} {2-1G} {2-1H} {2-1I} {2-g} {2-a})
      job "Prince"
      fin 680370
      dat 664554
    @P={2-1B}
   -> NIL            # only one result
If you are interested in the names of "Albert Edward"'s children:
   : (? (db nm +Person "Albert Edward" @P) (lst @K @P kids) (val @Kid @K nm))
    @P={2-1B} @K={2-1C} @Kid="Beatrice Mary Victoria"
    @P={2-1B} @K={2-1D} @Kid="Leopold George Duncan"
    @P={2-1B} @K={2-1E} @Kid="Arthur William Patrick"
    @P={2-1B} @K={2-1F} @Kid="Louise Caroline Alberta"
    @P={2-1B} @K={2-1G} @Kid="Helena Augusta Victoria"
    @P={2-1B} @K={2-1H} @Kid="Alfred Ernest Albert"
    @P={2-1B} @K={2-1I} @Kid="Alice Maud Mary"
    @P={2-1B} @K={2-g} @Kid="Victoria Adelaide Mary"
    @P={2-1B} @K={2-a} @Kid="Edward VII"
   -> NIL
db/3 can do a direct index access only for a single attribute ('nm' of '+Person' above). To search for several criteria at the same time, select/3 has to be used:
   : (?
      (select (@P)
         ((nm +Person "Edward") (nm +Person "Augusta" pa))  # Generator clauses
         (tolr "Edward" @P nm)                              # Filter clauses
         (tolr "Augusta" @P kids nm) )
      (show @P) )
   {2-1B} (+Man)
      kids ({2-1C} {2-1D} {2-1E} {2-1F} {2-1G} {2-1H} {2-1I} {2-g} {2-a})
      mate {2-f}
      nm "Albert Edward"
      job "Prince"
      fin 680370
      dat 664554
    @P={2-1B}
   -> NIL
select/3 takes a list of generator clauses which are used to retrieve objects from the database, and a number of normal Pilog filter clauses. In the example above the generators are All persons generated are possible candidates for our selection. The 'nm' index tree of '+Person' is traversed twice in parallel, optimizing the search in such a way that successful hits get higher priority in the search, depending on the filter clauses. The process will stop as soon as any one of the generators is exhausted. Note that this is different from the standard Prolog search algorithm.

The filter clauses in this example both use the pre-defined predicate tolr/3 for tolerant string matches (according either to the soundex algorithm (see the section Database Programming) or to substring matches), and filter objects that A more typical and extensive example for the usage of 'select' can be found in the 'qPerson' function in "doc/family.l". It is used in the search dialog of the demo application, and searches for a person with the name, the parents' and partner's names, the occupation and a time range for the birth date. The relevant index trees in the database are searched (actually only those trees where the user entered a search key in the corresponding dialog field), and a logical AND of the search attributes is applied to the result.

For example, press the "Select" button, enter "Elizabeth" into the "Mother" search field and "Phil" in the "Partner" search field, meaning to look for all persons whose mother's name is like "Elizabeth" and whose partner's name is like "Phil". As a result, two persons ("Elizabeth II" and "Anne") will show up.

In principle, db/3 can be seen as a special case of select/3. The following two queries are equivalent:
   : (? (db nm +Person "Edward" @P))
    @P={2-;}
    @P={2-1B}
    @P={2-R}
    @P={2-1K}
    @P={2-a}
    @P={2-T}
   -> NIL
   : (? (select (@P) ((nm +Person "Edward"))))
    @P={2-;}
    @P={2-1B}
    @P={2-R}
    @P={2-1K}
    @P={2-a}
    @P={2-T}
   -> NIL

https://picolisp.com/wiki/?tutpilog

02nov10    abu