Java 实现统一算法

Java 实现统一算法,java,unification,Java,Unification,在过去的5天里,我一直在研究统一算法在Prolog中的工作原理。 现在,我想用Java实现这样的算法 我认为最好的方法可能是操纵字符串,并使用一些数据结构(如堆栈)分解其部分 为了说明这一点: 假设用户输入为: a(X,c(d,X))=a(2,c(d,Y)) 我已经将其作为一个字符串,并将其拆分为两个字符串(表达式1和2)。 现在,我怎么知道下一个字符是变量还是常量等等, 我可以用嵌套的if来做,但在我看来这不是一个好的解决方案。。 我尝试使用继承,但问题仍然存在(我如何知道正在读取的字符类型?

在过去的5天里,我一直在研究统一算法在Prolog中的工作原理。 现在,我想用Java实现这样的算法

我认为最好的方法可能是操纵字符串,并使用一些数据结构(如堆栈)分解其部分

为了说明这一点:

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

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

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

(不太清楚“do It by nested”是什么意思,但如果你的意思是尝试读取表达式,并在遇到每个“(”时递归,那么这实际上是正确的方法之一——这就是ANTLR为你生成的代码的核心功能。)

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


(如果你用这种方式构造东西,那么以后插入一个合适的解析器就很容易了,它将生成与你之前一直手工构造的树相同的树。这将让你以一种相当简洁的方式分别处理这两个问题。)

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

关于米尔纳算法的一个很好的描述可以在阿霍、塞蒂和厄尔曼的《龙书》:《编译器:原理、技术和工具》中找到。(米尔纳算法还可以处理循环图的统一,而《龙书》将其作为进行类型推断的一种方法).从它的发音来看,你可以从学习一点语法分析中获益…这也是龙之书所涵盖的


编辑:其他答案建议使用解析器生成器;例如ANTLR。这是一个很好的建议,但是(从您的示例判断)您的语法非常简单,您还可以使用StringTokenizer和手写的递归下降解析器。事实上,如果您有时间(和倾向性)作为一个学习练习,双向实现解析器是值得的。

在开始学习语言的语义之前,必须将文本转换为易于操作的形式。此过程称为,语义表示称为(AST)

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

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

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