0

我在过去 5 天工作以了解统一算法在 Prolog 中的工作原理。现在,我想用Java实现这样的算法..

我认为也许最好的方法是使用诸如 Stacks 之类的数据结构来操作字符串并分解其部分。

说清楚:

假设用户输入是:a(X,c(d,X)) = a(2,c(d,Y))。

我已经将它作为一个字符串并将其拆分为两个字符串(Expression1 和 2)。现在,我怎么知道下一个字符是变量还是常量等等。我可以通过嵌套 if 来做到这一点,但在我看来这不是一个好的解决方案。我尝试使用继承,但问题仍然存在(如何我可以知道正在读取的字符类型吗?)

4

3 回答 3

1

首先,您需要解析输入并构建表达式树。然后应用 Milner 的统一算法(或其他一些统一算法)来计算变量到常量和表达式的映射。

可以在 Aho、Sethi 和 Ullman 的 Dragon Book:“编译器:原理、技术和工具”中找到对 Milner 算法的非常好的描述。(Milners 算法也可以应对循环图的统一,Dragon Book 将其作为一种进行类型推断的方式提出)。通过它的声音,您可以从学习一些关于解析的知识中受益……这也包含在 Dragon Book 中。

编辑:其他答案建议使用解析器生成器;例如 ANTLR。这是一个很好的建议,但是(从你的例子来看)你的语法非常简单,你也可以使用 StringTokenizer 和一个手写的递归下降解析器。事实上,如果您有时间(和意愿),那么值得以两种方式实现解析器作为学习练习。

于 2009-10-03T23:23:53.030 回答
0

听起来这个问题更多地与解析有关,而不是具体的统一。使用ANTLR之类的东西可能有助于将原始字符串转换为某种树结构。

(不清楚“通过嵌套执行”是什么意思,但是如果您的意思是您正在做诸如尝试读取表达式并在遇到每个“(”时递归),那么这实际上是正确的方法之一去做——这就是 ANTLR 为你生成的代码的核心。)

如果您对统一事物的机制比对解析更感兴趣,那么一种非常好的方法是直接在代码中构建内部表示,并暂时推迟解析方面。这在开发过程中可能会有点烦人,因为您的 Prolog 样式语句现在是一组相当冗长的 Java 语句,但它可以让您一次专注于一个问题,这通常很有帮助。

(如果您以这种方式构建事物,这应该可以直接在以后插入适当的解析器,这将产生与您之前手工构建的相同类型的树。这将使您能够以合理的方式分别解决这两个问题整洁的时尚。)

于 2009-10-03T23:21:58.590 回答
0

在开始处理语言的语义之前,您必须将文本转换为易于操作的形式。这个过程称为解析,语义表示称为抽象语法树(AST)。

Prolog 的简单递归下降解析器可能是手写的,但更常见的是使用诸如Rats 之类的解析器工具包!Antlr

在 Prolog 的 AST 中,您可能有 Term 类,而 CompoundTerm、Variable 和 Atom 都是术语。多态性允许复合术语的参数是任何术语。

然后,您的统一算法将统一任何复合词的名称,并递归地统一相应复合词的每个参数的值。

于 2009-10-03T23:25:01.033 回答