[英]How to call a predicate from another predicate in 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是一种与大多数其他语言截然不同的编程工具。 所以这有点像使用各种锤子很长一段时间,然后有人给你扳手,你想知道为什么它不能成为一把好锤子。
在Prolog中, 谓词是一种声明实体之间关系的方法。 如果你说foo(a, b)
那就意味着a
和b
之间a
叫做foo
的关系。 你可能已经看过这些例子: 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).
这里,计算Z
和4
gcd
并返回其值,然后将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
等,而不是参数中的离散项car
和cdr
。 例如,稍微更一般的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有一个非常不同的态度来计算...
您没有定义函数 ,而是定义参数之间的关系 。 我所知道的最相似和众所周知的语言是SQL。 将谓词视为表(或存储过程,当某些计算未由数据库引擎预定义时)。
car([H|_],H).
cdr([_|T],T).
car_of_cdr(L, Car) :- cdr(L, Cdr), car(Cdr, Car).
但由于列表的语法是该语言的核心部分,因此可以有更好的定义
car_of_cdr([_,X|_], X).
无论如何,我认为你应该花一些时间在一些Prolog教程上。 SO信息页面有更多信息......
:- use_module(support).
这意味着该模块将使用其他模块中编写的谓词。
<module_name>:<predicate_name>(<atoms / Variables>).
这样您就可以在另一个模块中调用谓词。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.