Projog provides a mechanism for "plugging in" or "injecting" implementations of PredicateFactory at runtime. This mechanism provides an easy way to configure and extend the functionality of Projog - including adding functionality not possible to define in pure Prolog syntax.
Rather than directly implementing PredicateFactory it is recommended to extend either AbstractSingleResultPredicate or AbstractPredicateFactory.
Example usage
If your project is configured using Maven then you can add a dependency on Projog by adding the following to your project's pom.xml:
<dependency>
<groupId>org.projog</groupId>
<artifactId>projog-core</artifactId>
<version>0.10.0</version>
</dependency>Contents of com/example/SingleResultPredicateExample.java:
package com.example;
import static org.projog.core.term.TermUtils.getAtomName;
import org.projog.core.predicate.AbstractSingleResultPredicate;
import org.projog.core.term.Atom;
import org.projog.core.term.Term;
/**
* uppercase(X,Y) - succeeds if the atom represented by Y is equal to an upper case version of the atom
* represented by X.
*
* @see RetryablePredicateExample
*/
public class SingleResultPredicateExample extends AbstractSingleResultPredicate {
@Override
public boolean evaluate(Term term1, Term term2) {
Atom upperCaseTerm1 = new Atom(getAtomName(term1).toUpperCase());
return term2.unify(upperCaseTerm1);
}
}Example of integrating org.projog.example.SingleResultPredicateExample into Projog:
?- pj_add_predicate(uppercase/2, 'org.projog.example.SingleResultPredicateExample').
yes
?- uppercase('The quick brown fox jumps over the lazy dog', X).
X = THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
yes
?- uppercase('The quick brown fox jumps over the lazy dog', 'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG').
yes
?- uppercase('The quick brown fox jumps over the lazy dog', 'THE QUICK BROWN BOX JUMPS OVER THE LAZY FOG').
no Contents of com/example/RetryablePredicateExample.java:
package com.example;
import org.projog.core.predicate.AbstractPredicateFactory;
import org.projog.core.predicate.Predicate;
import org.projog.core.term.Atom;
import org.projog.core.term.Term;
import org.projog.core.term.TermUtils;
/**
* split(X,Y) - compares Y to each of the comma-separated values represented by X.
*
* @see SingleResultPredicateExample
*/
public class RetryablePredicateExample extends AbstractPredicateFactory {
@Override
public Predicate getPredicate(Term arg1, Term arg2) {
String csv = TermUtils.getAtomName(arg1);
String[] split = csv.split(",");
return new RetryablePredicate(split, arg2);
}
private static class RetryablePredicate implements Predicate {
private final String[] split;
private final Term target;
private int idx;
RetryablePredicate(String[] split, Term target) {
this.split = split;
this.target = target;
}
@Override
public boolean evaluate() {
while (idx < split.length) {
target.backtrack();
String next = split[idx++];
if (target.unify(new Atom(next))) {
return true;
}
}
return false;
}
@Override
public boolean couldReevaluationSucceed() {
return idx < split.length;
}
}
}Example of integrating com.example.RetryablePredicateExample into Projog:
?- pj_add_predicate(split/2, 'com.example.RetryablePredicateExample').
yes
?- split('dog,cat,bird', X).
X = dog
yes ;
X = cat
yes ;
X = bird
yes ;
no