How use Prolog from Java?
In the context of a Java/Eclipse application I would like to use Prolog for a particular task. What are the available solutions and tools to do that, and associated pro and cons 开发者_运维问答?
I can launch an external Prolog interpreter generating the result in a file ? I can use a full Prolog Java Library (Prolog interpreter implemented in java) ? I can use a java library dedicated to the communication with an external Prolog interpreter ?
Thanks in advance for your help,
Manu
I would give GNU Prolog for Java a try. From the website:
GNU Prolog for Java is an implementation of ISO Prolog as a Java library
I'm using tuProlog Official Site, Code Repository on Android. They have a great embedded Prolog in the form on 1 Jar File. They are responsive too!
A quick google returns a list of options (alas not updated in 5 years).
As for pros/cons - as I see it
Native engine with bindings would be the worse option when it comes to distribution and integration, but may be faster than the native Java engines (but I would want proof first).
Java engine with API would lead to some awkwardness at integration points, but should be easy to distribute.
Prolog to bytecode compiler should handle integration between the two languages nicely, and would mean that you are not shipping prolog scripts with the binary (may be a disadvantage). Big disadvantage with this - none still seem to be a live.
Prolog-alike language to bytecode compiler, same as above, but some still seem to be floating about, also would require knowledge of a new language.
Java rules engine - I'd see this as the neatest solution. Rather than use two languages code the rules in a Java-y way, but it depends on how complicated the rules are to express in that way.
A second thing to consider is - is the project still being updated. From my quick google, few are. Prova and Mandarax are two exceptions from the latter options.
When looking at multi-threaded Prolog systems, there are different additional considerations. One desiderata is to have a separation between threads and logic engines. This was expressed here: http://www.cs.nmsu.edu/ALP/2011/03/concurrent-programming-constructs-and-first-class-logic-engines/
There are some Prolog systems that realize this separation. Jekejeke Prolog is also among these systems. There is a report (*) that shows how this separation can be put to use. In the various scenarios we see that the "thread" is provided by a system external to the logic engine:
- Terminal Deployment: Thread is the Java main thread.
- Standalone Deployment: Thread is the AWT/Swing thread.
- Applet Deployment: Thread is some browser thread.
- Servlet Deployment: Thread comes from web server pool.
- Client Deployment: Thread is the AWT/Swing thread.
Best Regards
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/15_stdy/08_deploy/package.html
You may also have a look at JPL http://www.swi-prolog.org/FAQ/Java.html
There is Projog which is a Prolog written in Java, but also provides a Prolog REPL:
Projog provides an implementation of the Prolog programming language for the Java platform. /.../
Projog can be used as a stand-alone console application or embedded in your Java applications as a Maven dependency.
projog.consultFile(new File("src/main/resources/test.pl"));
QueryStatement s1 = projog.createStatement("test(X,Y).");
s1.setTerm("X", new Atom("d"));
QueryResult r2 = s1.executeQuery();
while (r2.next()) {
System.out.println("Y = " + r2.getTerm("Y"));
}
or implementing predicates in Java:
public class SingleResultPredicateExample extends AbstractSingleResultPredicate {
@Override
public boolean evaluate(Term term1, Term term2) {
Atom upperCaseTerm1 = new Atom(getAtomName(term1).toUpperCase());
return term2.unify(upperCaseTerm1);
}
}
or:
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;
}
}
精彩评论