prolog - 如何在 Prolog 中从另一个谓词调用一个谓词?

标签 prolog

所以我刚开始使用 Prolog,我想知道两件事:

1)是否有内置函数(或者它们都称为谓词?)用于简单的事情,例如最多 2 个数字或数字的正弦等...如果有,我如何访问它们?

2) 如何从另一个谓词调用谓词?我写了两个谓词,称为 car 和 cdr。 car 返回列表的头部,而 cdr 返回没有头部的列表。但现在我想在 cdr 上调用汽车。以下是一些澄清示例:

car([3,4,5,5], H). would return H = 3

cdr([3,4,5,5],L). would return L = [4,5,5]

我要问的是我该如何做到这一点:

car(cdr[3,4,5,5]))

??

最佳答案

正如其他人所指出的,Prolog 中的谓词这样称呼是有原因的:它们实际上不是函数。许多 Prolog 新手一开始尝试将他们所知道的其他语言的功能映射到 Prolog,但通常会失败。 Prolog 是一种与大多数其他语言截然不同的编程工具。所以这有点像长时间使用各种锤子,然后有人递给你一把 Spanner ,你想知道为什么它不是一把好锤子。

在 Prolog 中,谓词是声明实体之间关系的一种方式。如果你说foo(a, b)这意味着 a 之间存在关系和bfoo 。您可能已经看过以下示例:knows(joe, jim).knows(jim, sally).您可以定义一个关系,例如:

remotely_acquainted(X, Y) :- knows(X, Z), knows(Z, Y), \+ knows(X, Y).

或者类似的东西。

谓词不返回值。它要么成功,要么失败。如果你有一系列用逗号分隔的谓词(“与”关系),并且 Prolog 遇到一个失败的谓词,它会备份(回溯)到最近的先前谓词,它可以通过其参数的不同实例化来再次成功,并移动再次转发。

为了增加一点困惑,Prolog 中有一些专门为算术表达式的计算而设计的谓词。它们的作用类似于函数,但它们是特殊情况。例如:

X is Y / gcd(Z, 4).

在这里,gcdZ4计算并返回其值,然后 Y除以该值,结果被实例化为 X。还有各种其他函数,例如 max/2 , sin/1等等。您可以在文档中查找它们。

算术比较运算符也以这种方式起作用(使用 =:=/2>/2</2 等与数字表达式)。所以如果你说:

X < Y + Z

Prolog 将考虑这些参数的数值评估,然后对它们进行比较。

话虽如此,Prolog 确实允许嵌入术语结构。你可以有这样的东西:

car(cdr([1,2,3]))

作为一个术语。 Prolog 不会解释它。解释由程序员决定。然后我可以创建一个谓词来定义这些术语的评估:

car([H|_], H).
cdr([_|T], T).

proc_list(car(X), Result) :-
    proc_list(X, R1),
    car(R1, Result), !.
proc_list(cdr(X), Result) :-
    proc_list(X, R1),
    cdr(R1, Result), !.
proc_list(X, X).

上述子句的删减可防止回溯至 proc_list(X, X)当我不想要的时候。

然后:

| ?- proc_list(car(cdr([1,2,3])), R).

R = 2

yes
| ?- proc_list(car(cdr(cdr([1,2,3]))), R).

R = 3

yes
| ?-

请注意,这是一个简单的案例,我可能没有捕捉到正确执行 car 序列的所有微妙之处。和cdr 。还可以使用=..使其更通用。和call等,而不是离散项 carcdr在参数中。例如,稍微笼统一点的proc_list可能是:

proc_list(Term, Result) :-
    Term =.. [Proc, X],               % Assumes terms have just one argument
    member(Proc, [car, cdr]),         % True only on recognized terms
    proc_list(X, R1),                 % Recursively process embedded term
    ProcCall =.. [Proc, R1, Result],  % Construct a calling term with Result
    call(ProcCall), !.
proc_list(X, X).

这种处理术语的技术确实远离了 Prolog 最擅长的关系行为,而是倾向于函数行为,但需要了解 Prolog 的工作原理。

关于prolog - 如何在 Prolog 中从另一个谓词调用一个谓词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22373912/

相关文章:

prolog - 如何在Prolog中应用通用量词?

c - 将任意大小的整数从 Prolog 传递到 C

prolog - 将 Prolog 代码翻译成 Lisp

Prolog 整数比较因 error_type 错误而失败

prolog - 将递归转换为尾递归?

list - 从 Prolog 中的列表中删除头部

prolog - prolog 中的全称量词和存在量词

prolog - 在列表中计数。帮助我理解这段代码

parsing - Prolog - 解析

Prolog 约束编程查找偶数和奇数