Pred 1.4
java.lang.Objectio.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.
first_call
is needed.call
is needed. So, the first_call
must create and return an object that can act on backtracking.post_call
is needed to handle it.
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 |
---|
Pro_Term
called_body
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
.
boolean
cut
cut
predicate. Rarely needed otherwise.
Usually false
. If set in first_call
, the calling clause is not backtracked behind the call of this predicate.
boolean
cutting
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.
boolean
exception
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.
Pro_Term
exit_value
exception
is set. Should be an integer.
boolean
forward
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.
Pro_TrailMark
Mark
See documentation of Pro_Trail
for details.
boolean
op_found
true
when first_call
is called. If set to false
the predicate is searched from the database after the return from first_call
.
Activation
sub_activation
null
in post_call
when called body is set to null
.
Pro_Trail
trail
See documentation of Pro_Trail
for details.
Method Detail |
---|
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
params
- the calling term with arguments as subterms
null
or an object for recall on backtrack or for post_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.
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.
public String toString()