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