【问题标题】:Defining (mathematical) function in Prolog在 Prolog 中定义(数学)函数
【发布时间】:2013-08-27 12:24:40
【问题描述】:

我知道 Prolog(逻辑编程)都是关于返回 true 和 false,并且函数是返回从列表到数字到布尔值的任何东西的东西。最初,Prolog 似乎没有函数的概念,而是依赖于统一,但是您可以执行以下操作:

?- X is log(42).
X = 3.7376696182833684.

所以似乎存在功能?或者这真的只是某种隐藏统一部分的语法糖?

如果它真的只是语法糖,那么如果我想定义一个像 log2 这样的数学“函数”,我该怎么做?

我当然可以使用统一:

log2(X,Result) :- Result is log(X)/log(2).

但是假设我想使用“语法糖函数样式”,所以我可以写:

?- X is log2(8).
X = 3.0.

如何在 Prolog 中做到这一点?

【问题讨论】:

  • 有一个已弃用的指令arithmetic_function 可以满足您的需求。假设您的 log2/2 谓词存在,指令 :- arithmetic_function(log2/1). 将使您的第二个示例工作。我不确定为什么不推荐使用它,但它似乎在 6.2.6 中仍然有效。
  • 我也想知道这种弃用,想问问 Jan W.。丹尼斯 M. 喜欢与 Amzi 一起使用的方法! Prolog 将定义“is”的替代方案(例如 iz/2 使用中缀语法)并构造规则来评估所需的任何附加功能。

标签: prolog operators user-defined-functions


【解决方案1】:

所以这只是统一..(感谢 mbratch 和 mat 的解释)

这就是我解决最初问题的方法,从而使我的代码在使用自定义数学函数时更具可读性:

:- op(900, xfy, <-).
R <- log2(Y) :- R is log(Y)/log(2), !.

% the two predicates below solves the problem with using mathematical operators
% together with self defined functions note that they should always be last
%
R <- X :-
    compound(X),
    X =..[OP, X2, X3],
    R2 <- X2,
    R3 <- X3,
    Expr =..[OP, R2, R3],
    R is Expr, !.
R <- X :- R is X, !.

那我可以写了:

?- X <- log2(8).
X = 3.0.

此外,最后两个谓词使得可以编写如下复合词:

?- X <- 17*log2(8) - 2.
X = 49.0.

请注意,您不能乱用 is/2,因此我有点用我自己的

编辑:添加了 mat 建议的语法糖,并添加了两个谓词,在将新定义的 log2 与其他数学运算符结合使用时解决了问题

【讨论】:

  • 您也可以在子句头部使用新定义的中缀运算符:R &lt;- log2(Y) :- R is ...
  • op 指令很有趣,可以为您提供一些有趣且有用的语法方法来表示谓词。 is 是一个内置谓词,因此您无法更改 is 的定义。 :)
【解决方案2】:

Prolog 是关于描述实体之间的关系。由于数学 函数 是一种特殊的关系(将输入与唯一定义的输出相关联),您可以使用 Prolog 来描述此类函数。在您的示例中,实现此关系的谓词称为is/2,而(is)/2 在Prolog 中也定义为中缀运算符,因此您可以这样写:

?- X is log(42).

代替前缀形式(当然也可以接受):

?- is(X, log(42)).

注意is/2 执行表达式的算术评估,并将第一个参数与结果统一起来。这不同于 X 与 Prolog 术语 log(42) 的统一。

请注意,is/2 不是真正的关系,因为您不能在其他方向使用它:

?- 0 is log(X).
ERROR: is/2: Arguments are not sufficiently instantiated

对此的解决方案是使用约束(例如,在实数上,称为 CLP(R)),它适用于所有方向。它们在许多现代 Prolog 系统中作为库或内置程序提供。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多