2

Prolog谓词定义中的输入和输出参数有什么区别吗?这与其他语言(如 Scheme 和 C)相比如何?

4

2 回答 2

3

我希望我能理解你的问题。你应该研究一下 Prolog 是如何实现统一的,因为它会让事情变得更清晰。反正:

简而言之,没有内置方法可以将 Prolog 谓词的参数声明为输入、输出或输入/输出。

在 C 中,你可以说:

void foo(int const *a, int *b)
{
    *b += *a;
}

您可以争辩说,在 的上下文中fooa是输入参数,而b是输出参数。在 Prolog 中,您可以在描述谓词时使用这种表示法,但无法在谓词定义的头部声明在调用谓词时必须绑定参数或自由变量。无论如何,纯 Prolog 中的大多数谓词都有可以是inputoutputinput/output的参数,具体取决于谓词的使用方式。查看SWI-Prolog 的列表库以获取许多示例。

您当然可以要求实例化参数或自由变量,但这是在谓词定义的主体中完成的:

add_2(A, B) :- integer(A), var(B), B is A+2.

将此与以下内容进行比较:

plus_2(A, B) :- integer(A), integer(B), B =:= A+2.

它检查 B=A+2 是否成立,而不是将 A 加 2 并将结果与​​ B 统一。integer/1,var/1其他验证术语类型的谓词不能在纯 Prolog 中实现。

在我对 Prolog 的非常有限的经验中,我注意到只要有足够的参数被实例化,就会尝试定义可以工作的谓词:

  1. 根据谓词的逻辑实例化其他变量
  2. 推断谓词所描述的参数之间的关系是否成立。

例如,length(List, Integer)可以告诉你一个列表有多长,制作一个给定长度的未实例化变量列表,或者检查列表是否那么长。

但是,您可以做的是在谓词定义的头部添加一个基本术语,例如foo(1)。这种谓词称为事实。头部带有基本术语的子句是定义递归谓词的递归结束的常用方法。

于 2013-04-15T09:20:02.647 回答
1

Prolog定义中的输入/输出参数有什么区别吗?

不,实际上参数可以是任何一个,具体取决于它的使用方式。Boris 的长度示例是一个很好的示例,因为您可以计算长度:

?- length([1,2,3], X).
X = 3.

或测试一个答案:

?- length([1,2,3], 3).
true.

或者生成指定长度的列表:

?- length(X, 3).
X = [_G273, _G276, _G279].

甚至生成列表和长度:

?- length(X, Y).
X = [],
Y = 0 ;
X = [_G15],
Y = 1 ;
X = [_G15, _G18],
Y = 2 ;
...

因此,您看到是否length/2可以实例化的任何一个参数,您仍然会得到有意义的答案。并非 Prolog 中的每个谓词都如此灵活,但很多都是。

这与其他语言(如 scheme 和 C )相比如何?

这是Prolog 和其他语言之间的主要区别。没有其他更知名的语言可以类似地帮助您理解它。这意味着,除其他差异外,没有隐含的“返回值”,您必须有一个参数才能将结果传回,但您不仅限于一个结果参数。在两个参数length/2都未实例化的情况下,它们都充当返回值。

按照惯例,您将希望编写谓词,以便在常见情况下输入参数位于输出参数之前(或者至少,以您选择的名称的合理方式)。

于 2013-04-15T14:51:37.577 回答