如何从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之间有一个叫做foo的关系.你可能已经看过这些例子:know(joe,jim).并且知道(吉姆,莎莉).你可以定义一个关系,比如:

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
| ?-

请注意,这是一个简单的案例,我可能没有捕捉到执行正确的汽车和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中的另一个谓词调用谓词? - 代码日志