CGI Interface

Introduction

The Amzi! Logic Server Common Gateway Interface (CGI) interface allows you to integrate Prolog logic with web servers through CGI scripts written in Prolog. The Prolog code can read information from a Web form and dynamically generate HTML to send back to the user.

A straight-forward class of applications for the CGI-Amzi! interface is intelligent form editors. Prolog code can be used to analyze user input from forms and then, based on that analysis, generate either responses or other HTML user input elements to gather or correct missing or wrong information.

Expert systems can be implemented that dynamically generate HTML forms to query the user, and, based on user answers, either generate more questions or provide answers in HTML to the user.

Expert systems are just one form of intelligent interaction enabled by the CGI-Amzi! interface. Others include intelligent tutorials, natural language processing applications, database or other information retrieval, and, of course, interactive games.

WebLS is another Amzi! product that is an example of the type of application you can implement using the CGI-Amzi! interface. WebLS is a custom rule engine that uses a simple rule language to let webmasters add expertise to their Web pages. The rule engine is written in Prolog and uses HTML specified in WebLS question and answer fields to communicate with the user.

Architecture

CGI provides a way for an application to communicate with a Web server. The Web server calls the CGI application when it receives information from the user, and the CGI application can send generated HTML back to the user through the Web server.

The executable file that the server calls is written in C, and is provided with full source code. That program starts the Amzi! Logic Server and loads the Prolog CGI script. Before calling the main entry point of the Prolog script, the CGI executable program first gathers information from the HTML form and asserts that information to the Prolog logicbase. This step is what allows the Prolog code to easily reason over the information entered by the user in the incoming HTML form.

The CGI executable than calls the Prolog portion of the CGI-Amzi! interface. This is a Prolog wrapper that provides many of the bookkeeping functions necessary for CGI. That Prolog program then calls predicates that are defined in the user-written Prolog script. From this point, the user Prolog program is processing the CGI data.

The Prolog program communicates back with the CGI interface through a number of extended predicates that are implemented in both the Prolog wrapper and C executable program.

Using the CGI Interface with Various Web Servers

Windows with IIS/PWS

Copy the .xpl file, the .exe (copied from acgi.exe), amzi.dll and amzi.cfg to the /InetPub/Scripts directory. Also, using the IIS or PWS Manager enable both "Scripts" and "Executables" on the Scripts directory.

Windows with Netscape FastTrack

Copy the .xpl file, the .exe (copied from acgi.exe), amzi.dll and amzi.cfg to the cgi-bin directory.

Solaris with Apache

Copy the .xpl file and acgi (renamed) to the /apache/cgi-bin directory. Use Apache directives to tell it where to find libamzi.so or copy libamzi.so to /lib. Use the Apache setEnv or passEnv directives to set the value of AMZI_DIR and put your amzi.cfg file in /amzi/config.

Implementation

The Amzi! implementation supports the current CGI 1.1 standard.

The CGI interface consists of two parts. First, there is a Prolog library which provides the basic framework for the script and many supporting functions. Second, there is a C program that invokes the script framework in the Prolog library and also provides some additional supporting functions. The files are:

In the samples/internet/cgi subdirectory, you will find an examples that use the CGI interface.

Building the C Program

The first step is to compile and link amzicgi.c and amzisub.c into an executable. This is provided in amzi/lsapis/cgi/acgi[.exe].

As currently written, the C program loads an .xpl file with the same name. For example, acgi.exe will load acgi.xpl.

Writing the Prolog Script

The second step is to write a Prolog script that conforms to the framework provided in acgi.pro. You need to define the following predicates:
cgiLoad/0
This predicate needs to consult or load any external Prolog modules, rule sets or logic-bases. All the cgi and system variables are already asserted into the logicbase and the output file has been opened.
cgiMain/0
This is your main script which processes get and post requests from forms.
cgiErrorNote/0
This outputs additional information (via cgiSend) when an unexpected but fatal error occurs. Generally you will want to output who to contact about the problem.

You must link with both the acgi and list libraries to create your xpl file.

CGI Variables

Within your CGI script (cgiMain) you will want to access the values entered into the forms. These are all dynamically asserted as:
fact(field_name, value)
The field names are Prolog atoms and the values are Prolog strings unless they begin with backslash or square bracket, in which case they are asserted as Prolog terms.

You script can also access the values of many CGI variables. The Amzi! implementation uses lowercase versions of the standard CGI names (replacing spaces with underscores) and create predicates of arity 2 representing each value. For example:

cgi(content_length, $1462$)
All cgi, extraheader and accept variables have string values. All system variables have atom values.

The following table lists the possible CGI variables that may be set. Web servers differ in the variables they set and the format of the values they use.
 
Standard CGI Name Predicate Name
auth_name cgi
auth_user cgi
auth_type cgi
cgi_version cgi
content_file cgi
content_length cgi
content_type cgi
cookie extraheaders 
gateway_interface cgi
http_cookie extraheaders
http_from cgi 
http_referer cgi
http_user_agent cgi
logname cgi
path_info cgi
path_translated cgi
query_string cgi
referer_url cgi
remote_addr cgi
remote_host cgi
remote_user cgi
request_method cgi
request_range cgi
script_name cgi
server_admin cgi
server_name cgi
server_port cgi
server_protocol cgi
server_software cgi
user_agent cgi
debug_mode system
gmt_offset system

There are some additional system variables that affect the operation of the functions provided by acgi.pro. These are:

'Log File'
This is the name of the file to write logging information to (via cgiLog). It is the pathname passed to the operating system to open the file. It must be an atom. If you have not defined a log file, then all calls to cgiLog are ignored.
'Log File URL'
This is the URL of the log file for easy access to the file from your web browser.

CGI Predicates

All CGI predicates provided by acgi.pro and by amzisub.c begin with 'cgi'. They are:
cgiExpandChars(InputList, OutputList)
Given a character list, these clauses expand special characters into their proper HTML representations, e.g. > becomes > This could be used by the error handler when reporting syntax (read) errors as the buffer contains parts of the logic-base which include HTML tags which are not to be interpreted, simply displayed.
cgiSend(ListOrTerm)
Outputs the list of terms or the term (which may be a string, atom, number, etc. to the output file.
cgiSendLocalHTMLFile(FileName)
Outputs the contents of an existing HTML text file to the output file. You must output the header separately before calling this function. This allows you to intermix "canned" HTML with generated HTML.
cgiSendURL(URL)
Tells the server to redirect to the specified URL.
cgiAskField(Key, Prompt, Length, Separator, DefaultValue)
Outputs the Prompt into the current HTML output file with the input box of the specified Length and DefaultValue, followed by the Separator.
cgiAskYesNo(Key, Prompt, Separator)
Outputs the Prompt and asks for a yes, no or unknown radio button to be checked.
cgiAskMenu(Key, Prompt, Choices, Type, Separator)
Outputs the Prompt and a checkbox, radio or drop-down menu containing the items in the Choices list, each separated by the Separtor.
cgiAskTextbox(Key, Prompt, Length, Separator)
Outputs a textarea with Length rows followed by Separator.
cgiLog(Stuff)
If logging is enabled (by the existence of a system fact named 'Log File') then write Stuff to it. The first write causes the file to be opened, and all the system, cgi and facts to be written to it. The file is closed automatically when the script finishes.
cgiLogSuspend
Suspends output to the log file via cgiLog calls.
cgiLogResume
Resumes output to the log file via cgiLog calls.
cgiDecodeURL(URL, DecodedURL)
Converts +'s to spaces and &nn's to characters in a URL string.
cgiExtractFileName(Path, File)
Extracts the name of a program or file from the end of a pathname.
cgiExtractPath(Path, PathOnly)
Removes the ending file name from a full path.
cgiPathSeparator(SepChar)
Returns the path separator character for the current operating system.

Copyright ©1987-2011 Amzi! inc. All Rights Reserved. Amzi! is a registered trademark and Logic Server is a trademark of Amzi! inc.