10.44.3 A First Example

This section provides an example to illustrate how PrologBeans can be used. This application has a simple Java GUI where the user can enter expressions that will be evaluated by an expression evaluation server.

     import java.awt.*;
     import java.awt.event.*;
     import javax.swing.*;
     import se.sics.prologbeans.*;
     
     public class EvaluateGUI implements ActionListener {
     
       private JTextArea text = new JTextArea(20, 40);
       private JTextField input = new JTextField(36);
       private JButton evaluate = new JButton("Evaluate");
       private PrologSession session = new PrologSession();
     
       public EvaluateGUI() throws java.io.IOException
         {
         if ((Integer.getInteger("se.sics.prologbeans.debug", 0)).intValue() != 0) {
     	  session.setTimeout(0);
           }
         JFrame frame = new JFrame("Prolog Evaluator");
         Container panel = frame.getContentPane();
         panel.add(new JScrollPane(text), BorderLayout.CENTER);
         JPanel inputPanel = new JPanel(new BorderLayout());
         inputPanel.add(input, BorderLayout.CENTER);
         inputPanel.add(evaluate, BorderLayout.EAST);
         panel.add(inputPanel, BorderLayout. SOUTH);
         text.setEditable(false);
         evaluate.addActionListener(this);
         input.addActionListener(this);
     
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.pack();
         frame.setVisible(true);
     
         session.connect();
       }
     
       public void actionPerformed(ActionEvent event) {
         try {
           Bindings bindings = new Bindings().bind("E",
                               input.getText() + '.');
           QueryAnswer answer =
             session.executeQuery("evaluate(E,R)", bindings);
           PBTerm result = answer.getValue("R");
           if (result != null) {
             text.append(input.getText() + " = " + result + '\n');
             input.setText("");
           } else {
             text.append("Error: " + answer.getError() + '\n');
           }
         } catch (Exception e) {
           text.append("Error when querying Prolog Server: " +
                       e.getMessage() + '\n');
           e.printStackTrace();
         }
       }
     
       public static void main(String[] args) throws java.io.IOException
       {
         new EvaluateGUI();
       }
     }

The Java code above first sets up the GUI with a text area for showing results, a text field for entering expressions, and a button for requesting an evaluation (the constructor EvaluateGUI()). It will also add itself as ActionListener on both the text field and the button. The method actionPerformed(ActionEvent event) will be called whenever the user has pressed <RET> or clicked on the button. actionPerformed first binds the variable E to the value of the text field, and then sends the query to the Prolog server with session.executeQuery("evaluate(E,R)", bindings);. If everything goes well, the Prolog server will return an answer (bound to R), which will be appended to the text area.

     :- module(evaluate,[main/0,my_predicate/2]).
     :- use_module(library(prologbeans)).
     :- use_module(library(codesio), [read_from_codes/2]).
     
     %% Register acceptable queries and start the server (using default port)
     main:-
         register_query(evaluate(C,P), my_predicate(C,P)),
         start.
     
     %% We have received a code-list
     %% which needs to be converted into an expression
     my_predicate(Chars, P) :-
         read_from_codes(Chars, X),
         P is X.

The Prolog code above first defines the module and imports the needed modules. Then, in the main/0 predicate, it configures the server to answer queries on the form evaluate(C,P) and starts the server. The last few lines defines the predicate my_predicate(Chars, P), which is the predicate that performs the evaluation. Note that, here, the expression to evaluate is represented as a code-list and must be converted into a term before evaluation.

In general, arbitrary Prolog terms can be passed to the client via this mechanism, including terms containing unbound variables. However, any unbound variables with attributes or blocked goals attached to them will be replaced by plain, brand new variables. This is analogous to the way attributed variables are handled in terms that are written, copied, asserted, gathered as solutions to findall/3 and friends, or raised as exceptions. If the attributes must be passed to the client, the Prolog code can obtain them by using copy_term/3 (see ref-lte-cpt).

Please note: the environment variable SP_PATH as used here is meant to be a shorthand for the SICStus Prolog installation directory, and does not need to be set explicitly.

To start the example, first start the Prolog server by going to the %SP_PATH%\library\prologbeans\examples\evaluate (Windows), or $SP_PATH/library/prologbeans/examples/evaluate (UNIX/Linux) directory and type:

     % sicstus -l evaluate.pl --goal "main."

To start the GUI type (from the same directory as above):

     > java -classpath "%SP_PATH%\bin\prologbeans.jar;." EvaluateGUI (Windows), or
     % java -classpath "$SP_PATH/bin/prologbeans.jar:." EvaluateGUI (UNIX)

Send feedback on this subject.