【问题标题】:Prolog 'is/2' predicate implementationProlog 'is/2' 谓词实现
【发布时间】:2014-01-26 21:04:43
【问题描述】:

'is/2' Prolog 谓词是如何实现的? 我知道

X is 3*4

等价于

is(X, 3*4)

但是谓词是使用命令式编程实现的吗? 换句话说,实现与下面的C代码是等价的吗?

if(uninstantiated(x)) 
{
    X = 3*4;
}
else
{
    //signal an error
}

还是使用声明式编程和其他谓词来实现?

【问题讨论】:

    标签: prolog imperative-programming declarative-programming


    【解决方案1】:

    显然,这取决于您的 Prolog,但任何实际的实现都将在 C 或其他命令式语言中完成其肮脏的工作。 is/2的一部分可以在纯Prolog中模拟:

    is(X, Expr) :-
        evaluate(Expr, Value),
        (var(X) ->
            X = Value
        ;
            X =:= Value
        ).
    

    evaluate 是一个知道算术表达式的巨大谓词。也有一些方法可以在纯 Prolog 中实现大部分内容,但这既缓慢又痛苦。例如。如果您有一个添加整数的谓词,那么您也可以使用以下(愚蠢的)算法将它们相乘:

    evaluate(X + Y, Value) :-
        % even this can be done in Prolog using an increment predicate,
        % but it would take O(n) time to do n/2 + n/2.
        add(X, Y, Value).
    evaluate(X * Y, Value) :-
        (X == 0 ->
            Value = 0
        ;
            evaluate(X + -1, X1),
            evaluate(X1, Y, Value1),
            evaluate(Y + Value1, Value)
        ).
    

    这些都不能保证是实际的或正确的;我只是在展示如何在 Prolog 中实现算术

    【讨论】:

    • 谢谢。以及如何在Prolog中实现增量谓词(用于'is/2'的实现)。我查了一下,但我只找到了使用'is/2'的增量实现。我问这一切是因为我很好奇 Prolog 是否可以是纯的(如“一切都是谓词”)。
    • @octavian is/2 是一个谓词。如果您的意思是 is 应该双向工作,您会意识到对于一般情况这并不完全有用(2 是 1+1;2 是 0+2;2 是 4/2;2 是 sqrt(4); ...)。但是,约束逻辑编程更接近您的意思。
    • 仔细阅读您的答案,这并不完全正确。最有可能的是,is/2 示例中的 if/else 不是必需的;相反,您将评估 Expr 并尝试将其与 X 统一。这就是为什么is/2=:=(算术相等)可以用相同的参数得到不同的答案。
    • @octavian 我认为您不能在纯 Prolog 中实现增量,至少不能在常规数字上实现。您可以在位或 Church 数字列表中实现它,以在纯 Prolog 中实现算术。
    【解决方案2】:

    取决于 Prolog 的版本;例如,CProlog(不出所料)是用 C 编写的,因此所有内置谓词都是用命令式语言实现的。

    【讨论】:

      【解决方案3】:

      Prolog 是为语言解析而开发的。所以,像

      这样的算术表达式
      3 + - ( 4 * 12 ) / 2 + 7
      

      after parsing 只是一个序言词(代表解析树),operator/3 提供语义来指导解析器的操作。对于基本的算术表达式,术语是

      • '-'/2。否定
      • '*'/2'/'/2。乘法、除法
      • '+'/2'-'/2。加法、减法

      上面的示例表达式被解析为

      '+'( '+'( 3 , '/'( '-'( '*'(4,12) ) , 2 ) ) , 7 )
      

      'is'/2 只是对代表右侧的解析树进行递归遍历,以与 RPN(反向波兰表示法)计算器几乎相同的方式评估每个术语。一旦对该表达式求值,结果将与左侧统一。

      每个基本操作(加、减、乘、除等)都必须在机器代码中完成,因此在一天结束时,会调用一些机器代码例程来计算每个基本操作的结果。

      is/2 是完全用原生代码编写还是主要用 prolog 编写,只用原生代码编写叶操作,这在很大程度上是一种实现选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多