繁体   English   中英

传递Prolog谓词的结果

[英]Passing the Results of a Prolog Predicate

如何评估prolog谓词作为参数传递的结果? 我正在尝试编写代码来反转列表中的元素对:

swap([A,B,C,D,E,F],R).

我想要结果:

[B,A,D,C,F,E]

但我得到了这个结果:

append(append(append([],[B,A],[D,C],[F,E])))

这是我的代码:

swap(L,R) :- swapA(L,[],R).
swapA([],A,A).
swapA([H,H2|T],A,R) :-  swapA(T, append(A,[H2,H]), R).

谢谢。

几件事:

  • 变量以大写字母开头,如果你想将一个原子与变量区分开来,请将它包装在'['A','B','C','D','E','F']
  • 您不需要追加成功实现此谓词。 使用append时复杂性更差。
  • 因为你不需要追加,你也不需要3个参数,2就足够了

这是一个建议:

swapA([], []).
swapA([X, Y|T], [Y, X|R]) :- swapA(T, R).

如果您希望在列表中包含奇数个元素时保留谓词,请考虑添加另一个基本案例:

swapA([X], [X]).

你不能像调用函数一样调用Prolog谓词。 它没有返回任何东西。 append(A,[H2,H])传递给swap时,它会将其解释为数据,而不是代码。

Prolog子句创建N个逻辑变量之间的关系。 这意味着理论上Prolog谓词中没有“输入”和“输出”的概念,您可以使用实例化和非实例化变量的任意组合进行查询,并且语言将为您找到有意义的关系:

1 ?- append([a],[b,c],[a,b,c]).
true.

2 ?- append([a],[b,c],Z).
Z = [a, b, c].

3 ?- append([a],Y,[a,b,c]).
Y = [b, c].

4 ?- append(X,[b,c],[a,b,c]).
X = [a] ;
false.

5 ?- append([a],Y,Z).
Z = [a|Y].

6 ?- append(X,[b,c],Z).
X = [],
Z = [b, c] ;
X = [_G383],
Z = [_G383, b, c] ;
X = [_G383, _G389],
Z = [_G383, _G389, b, c] . % etc

7 ?- append(X,Y,[a,b,c]).
X = [],
Y = [a, b, c] ;
X = [a],
Y = [b, c] ;
X = [a, b],
Y = [c] ;
X = [a, b, c],
Y = [] ;
false.

8 ?- append(X,Y,Z).
X = [],
Y = Z ;
X = [_G362],
Z = [_G362|Y] ;
X = [_G362, _G368],
Z = [_G362, _G368|Y] . % etc

9 ?- 

实际上,由于以不会产生无限循环的方式表达关系的限制,并非每个谓词都能被调用。 其他原因可能是额外的逻辑特征,如算术。 当您看到谓词记录为:

pred(+Foo, -Bar, ?Baz)

这意味着它期望Foo被实例化(即统一到另一个非var), Bar是一个自由变量而Baz可以是任何东西。 同样的谓词也可以有多种方式来调用它。

这就是你不能将Prolog关系视为一种函数的原因。 如果你传递一个化合物作为参数,那么这些子句可能只是将它视为一个复合,除非它专门设计为将其作为代码处理。 一个例子是call/1 ,它将其参数作为代码执行。 is=:=<和其他算术运算符也会做一些解释,以防你传递cos(X)类的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM