在 Java/Eclipse 应用程序的上下文中,我想使用 Prolog 来完成特定任务。有哪些可用的解决方案和工具可以实现这一点,以及相关的优缺点?
我可以启动外部 Prolog 解释器并在文件中生成结果吗? 我可以使用完整的 Prolog Java 库(用 java 实现的 Prolog 解释器)吗? 我可以使用专用于与外部 Prolog 解释器通信的 java 库吗?
预先感谢您的帮助,
马努
我会尝试一下 GNU Prolog for Java。来自网站:
GNU Prolog for Java 是 ISO Prolog 作为 Java 库的实现
快速谷歌返回一个选项列表(唉,5年没有更新了)。
至于优点/缺点 - 据我所知
带有绑定的本机引擎在分发和集成方面是更糟糕的选择,但可能比本机 Java 引擎更快(但我首先想要证明)。
带有 API 的 Java 引擎 会在集成点导致一些尴尬,但应该很容易分发。
Prolog 到字节码编译器 应该很好地处理两种语言之间的集成,并且意味着您不会随二进制文件一起传送 prolog 脚本(可能是一个缺点)。这有一个很大的缺点 - 似乎没有一个是活的。
类似于 Prolog 的语言到字节码编译器,与上面相同,但有些似乎仍然浮动,也需要新语言的知识。
Java 规则引擎 - 我认为这是最巧妙的解决方案。不是使用两种语言以 Java 方式编码规则,而是取决于以这种方式表达规则的复杂程度。
要考虑的第二件事是 - 该项目是否仍在更新。从我的快速谷歌来看,很少有。 Prova 和 Mandarax 是后一种选择的两个例外。
在查看多线程 Prolog 系统时,有不同的 额外的考虑因素。一个愿望就是分开 线程和逻辑引擎之间。这里表达了这一点: http://www.cs.nmsu.edu/ALP/2011/03/concurrent-programming-constructs-and-first-class-logic-engines/
有一些 Prolog 系统实现了这种分离。杰克杰克 Prolog 也是这些系统之一。有一份报告 (*) 显示 如何利用这种分离。在各种场景中 我们看到“线程”是由外部系统提供的 逻辑引擎:
致以诚挚的问候
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/15_stdy/08_deploy/package.html
您也可以看看 JPL http://www.swi-prolog.org/FAQ/Java.html
有Projog,它是用Java编写的Prolog,而且还提供了Prolog REPL:
Projog 提供 Prolog 编程语言的实现 对于Java平台。 /.../
Projog 可以用作独立的控制台应用程序或嵌入到 您的 Java 应用程序作为 Maven 依赖项。
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"));
}
或在 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);
}
}
或:
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;
}
}