【问题标题】:implementing unification algorithm实现统一算法
【发布时间】:2009-10-03 22:47:30
【问题描述】:

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

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

说清楚:

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

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

【问题讨论】:

    标签: java unification


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        【解决方案3】:

        在处理语言的语义之前,您必须将文本转换为易于操作的形式。这个过程称为parsing,语义表示称为abstract syntax tree (AST)。

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

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

        然后你的统一算法变成统一任何复合词的名称,并递归地统一对应复合词的每个参数的值。

        【讨论】:

          猜你喜欢
          • 2011-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-29
          • 2016-11-06
          • 2020-05-18
          相关资源
          最近更新 更多