Pred 1.4


io.github.JalogTeam.jalog
Class Pred

java.lang.Object
  extended by io.github.JalogTeam.jalog.Pred

public class Pred
    

Class Pred is the base class for all classes that implement Prolog primitive predicates.

For each built-in predicate a subclass of Pred is needed. Each built-in predicate must be introduced in BuiltIns class.

Each subclass of Pred must implement the static method first_call.

If other results are possibly produced on backtrack, first_call must create an object of this subclass and initialize it with any data that is needed on backtrack. The created object must be returned as the value of this function.

Another case where an object of this class must be created and returned is when some Prolog code (which may be received by a parameter or otherwise) needs to be executed.

If no action is needed after returning from first_call null should be returned.

If first_call always returns null no other methods should be implemented.

Other methods of Pred may be overridden as needed.

The structure depends on the overall behavior of the predicate.

In the simplest case the general structure of a subclass of Pred:

    public class Pred_example extends Pred
    {
      public static Pred first_call(Pro_TermData_Compound params) {

        // You may want to take parameters to local variables:
        Pro_Term first_param = params.subterm[0].getRealNode();
        Pro_Term second_param = params.subterm[1].getRealNode();
        ... // more parameters as needed

        ... // other declarations as needed

        forward = false; // default fail

        // Identify flow pattern and data types, and act accordingly.

        String first_type = first_param.getType();
        String second_type = second_param.getType();
        if (first_type != Jalog.OPEN) {
          // first_param is bound

          // check type
          if (first_type == Jalog.DATATYPE1) {
            Pro_TermData_Datatype1 first = (Pro_TermData_Datatype1)first_param.data;

            // compute result_value for second_param
            ... // computations as needed
            Pro_Term result_value = Pro_Term.m_type(...);
            
            // Unify result_value and second_param
            forward = result_value.unify(second_param, trail);
          }

        } else if (second_type != Jalog.OPEN) {
          // first_param is open and second_param is bound

          // check type
          if (second_type == Jalog.DATATYPE2) {
            Pro_TermData_Datatype2 second = (Pro_TermData_Datatype2)second_param.data;
          
            // compute result_value for first_param
            ... // computations as needed
            Pro_Term result_value = Pro_Term.m_type(...);
            
            // Unify result_value and first_param
            forward = result_value.unify(first_param, trail);
          } else if (second_type == Jalog.DATATYPE3) {
            Pro_TermData_Datatype3 second = (Pro_TermData_Datatype3)second_param.data;
            ...
          }
        
        }
        // fails if both parameters are open
        
        /*
          // if an error message wanted
          op_found = false; 
          
          // if an exception is wanted
          exception = true;
          exit_value = Pro_Term.m_integer(error_code);
        */
          
        return null;
        
      }
 
    }

If backtracking may produce other results or other processing is needed then the method call is needed.

    public class Pred_example extends Pred
    {
      // This data is used when backtracking to enable finding the next solution.
      Pro_Term param_1;
      Pro_Term param_2;     
      ... // more declarations as needed
      int clause_number; // for example
      
      public static Pred first_call(Pro_TermData_Compound params) {

        Pred_example state = null;

        // You may want to take parameters to local variables:
        Pro_Term first_param = params.subterm[0].getRealNode();
        Pro_Term second_param = params.subterm[1].getRealNode();
        ... // more parameters as needed

        ... // other declarations as needed
        
        forward = false; // default fail may be useful

        // Identify flow pattern and data types and act accordingly.

        String second_type = second_param.getType();
        if (second_type == Jalog.OPEN) { // (i,o)(o,o)
          // Backtrack cannot produce another result, state = null

          ... // declarations as needed
        
          ... // computations as needed
          
          Pro_Term second_value = Pro_Term.m_type(...);

          // unify result data to parameter if needed
          forward = second_value.unify(second_param, trail);
        } else { // (i,i) (o,i)
          if (second_type == Jalog.DATATYPE2) {
            ... // declarations as needed
            
            // If the data block of a term is needed:
            Pro_TermData_Datatype2 second_data = 
                (Pro_TermData_Datatype2) second_param.getData();
          
            ... // computations as needed
            
            // Backtrack may produce another result, state = new object
            state = new Pred_example();
            state.param_1 = first_param;
            state.param_2 = second_param;
            // initialize other state fields
            state.clause_number = 1; // for example

            trail.mark(state.Mark); // set backtrack point
            
            state.call(); // if the first result is computed the same way as
                          // other results, otherwise compute it here
          }
        }

        return state;
        
      }
 
      public void call()
      {
        // This is called on backtrack

        ... // declarations as needed
        
        // Variable bindings must be retracted on backtrack!
        trail.backtrack(Mark);
        forward = false; // default fail

        while((!forward) && another result is possible) {
          // This loop can be omitted if not needed.
          
          // Compute another result 
          if ( another result found ) {

            Pro_Term result_value = Pro_Term.m_type(...);
            
            // Unify result_value and param_1
            forward = result_value.unify(param_1, trail, Mark);
            // unify other results as needed:
            if (forward) forward = ... .unify(..., trail, Mark);
            ...

          }
        }
      }
    }

If a build-in predicate needs to execute some code (e.g. a parameter) then the code to be executed must be assigned to the field called_body as a list. If some processing is needed after the execution of the called_body, it is done in the method post_call.

A simple example of post_call is in the predicate not:

    // Pred_not.java

    package io.github.JalogTeam.jalog;

    import java.io.*;

    public class Pred_not extends Pred
    {
      public static Pred first_call(Pro_TermData_Compound data) {

        Pro_Term[] items = {data.subterm[0]};
        Pred_not state = new Pred_not();
        state.called_body = Pro_Term.m_list(items); 
          // called_body will be executed after the return

        return state;
      }

      public void post_call()
      {
        // now called_body has been executed
        forward = !forward;    // This inverts the result
        sub_activation = null; // no recall to called_body
        called_body = null;    // no recall to called_body 
      }
    }

If the called body throws an exception (calls exit) then post_call is not called. However, in order to catch the exception here this class must exted Pred_trap instead of Pred. On entry to post_call the variable exception is true if an exception was thrown and false otherwise. The exit code is in the variable exit_value.


Field Summary
Pro_Term called_body
           Used in e.g. not.
boolean cut
           Used in cut.
static boolean cutting
           Used in cut.
static boolean exception
           Set in e.g. exit.
static Pro_Term exit_value
           Set in e.g. exit.
static boolean forward
           Value true controls and indicates forward execution.
Pro_TrailMark Mark
           Controls backtracking of unifications.
static boolean op_found
           Set true when right code for this predicate.
Activation sub_activation
           For the inference engine.
static Pro_Trail trail
           Controls backtracking of unifications.
 
Method Summary
 public void call()
           Called in backtrack.
 public static Pred first_call(Pro_TermData_Compound params)
           Called when the predicate is executed first time.
 public void post_call()
           Called e.g. in not after sub predicates are executed.
 public String toString()
           Converts predicate status to string for debugging.
 

Field Detail

called_body

Pro_Term called_body
Initialized to null. Rarely needed.

This field is needed when Jalog code is executed by a built-in predicate. The value to be assigned must be a list that can be interpreted as a predicate body. The list is executed after returning from the method that has set the called_body.

Set called_body and sub_activation to null in call and post_call if no more execution is needed.

Typically called_body is a singlet list containing a subterm of params received in first_call.


cut

boolean cut
Used in cut predicate. Rarely needed otherwise.

Usually false. If set in first_call, the calling clause is not backtracked behind the call of this predicate.


cutting

boolean cutting
Used in cut predicate. Rarely needed otherwise.

Usually false. If set in call when forward is false, the remaining clauses of the calling predicate are not called. Instead, the predicate fails.


exception

boolean exception
Set in exit. Otherwise used in error situations.

Transfers execution to the exception handler argument of the latest active trap call, or exits the program if none is active. When set the exit_value must be set to desired exit code.


exit_value

Pro_Term exit_value
The desired exit code. Needed when exception is set. Should be an integer.

forward

boolean forward
The value indicates and controls the direction of execution.

On entry to call or post_call true indicates forward execution and false indicates backtracking.

On return from call or post_call true indicates success and causes forward execution, and false indicates failure and causes backtracking.


Mark

Pro_TrailMark Mark
Controls backtracking of unifications.

See documentation of Pro_Trail for details.


op_found

boolean op_found
Rarely needed. Is true when first_call is called. If set to false the predicate is searched from the database after the return from first_call.

sub_activation

Activation sub_activation
Must be set to null in post_call when called body is set to null.


trail

Pro_Trail trail
Used for cancelling unifications on backtracking.

See documentation of Pro_Trail for details.


Method Detail

first_call

public static Pred first_call(Pro_TermData_Compound params)

The method first_call must be implemented for every built-in predicate.

System executes first_call when this predicate is called. The argument params contains the arguments of the call in the array subterm and the number of arguments in the field arity.

The method call can be called from first_call if the same algorithm is useful.

The field forward is true when first_call is entered. On return forward must indicate succes with true or failure with false.

If other results are possibly produced on backtrack, or if called_body is used, first_call must create an object of its class and initialize it with any data that is needed on backtrack or post_call. The created object must be returned as the value of this function.

If no other results may be produced on backtrack, and post_call is not used, null must be returned. null must also be returned if forward is false

Parameters:
params - the calling term with arguments as subterms
Returns:
null or an object for recall on backtrack or for post_call

call

public void call()

The default implementation does nothing. A subclass may override this.

System calls this on backtrack. This can be called by first_call, too. If the system calls this on backtrack, forward is false.

Before returning forward must be set to true for success or to false for failure.


post_call

public void post_call()

This is called when called_body is executed or has failed. The field forward is true after success or false after failure.

Before returning forward must be set to true on success or to false on failure.

called_body and sub_activation must be set to null unless an execution of the same or another body is wanted. Otherwise, called_body is executed and post_call called again.

The default implementation does nothing. A subclass may override this.


toString

public String toString()
For debugging. Prints some data of the predicate instance. Usually, not necessary to override in subclasses


Authors: Mikko Levanto, Ari Okkonen