Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/prolog/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 如何计算列表中元素的索引?_Prolog - Fatal编程技术网

Prolog 如何计算列表中元素的索引?

Prolog 如何计算列表中元素的索引?,prolog,Prolog,我开始使用prolog,而且有Java背景,这对我来说非常困难,所以这里有一个愚蠢的问题: 您将如何编写一个indexOf谓词来给出给定列表中给定元素的索引 我的第一个问题是关于谓词算术:我想它应该是3,比如: indexOf(List,Element, Index) :- ...... 我说得对吗?这可能已经存在于内置库中,但我想学习如何编写它。谢谢您的帮助。您可以递归执行:假设基于0的索引(否则只需在第一个子句中将0更改为1) 如果您只想找到第一个外观,可以添加一个切口(!)以避免回溯 i

我开始使用prolog,而且有Java背景,这对我来说非常困难,所以这里有一个愚蠢的问题:

您将如何编写一个indexOf谓词来给出给定列表中给定元素的索引

我的第一个问题是关于谓词算术:我想它应该是3,比如:

indexOf(List,Element, Index) :- ......

我说得对吗?这可能已经存在于内置库中,但我想学习如何编写它。谢谢您的帮助。

您可以递归执行:假设基于0的索引(否则只需在第一个子句中将0更改为1)

如果您只想找到第一个外观,可以添加一个切口(!)以避免回溯

indexOf([Element|_], Element, 0):- !.
indexOf([_|Tail], Element, Index):-
  indexOf(Tail, Element, Index1),
  !,
  Index is Index1+1.

人们应该更喜欢使用尾部递归:

indexOf(V, [H|T], A, I)
:-
    Value = H, A = I, !
;
    ANew is A + 1,
    indexOf(V, T, ANew, I)
.

indexOf(Value, List, Index)
:-
    indexOf(Value, List, 0, Index)
.

indexOfWithoutFailure(Value, List, Index)
:-
    indexOf(Value, List, 0, Index)
;
    Index = -1
.
一些示例查询:

?- indexOf(d, [a, b, c, d, e, f], Index).
Index = 3.

?- indexOf(x, [a, b, c, d, e, f], Index).
false.

?- indexOfWithoutFailure(x, [a, b, c, d, e, f], Index).
Index = -1.

如果要获取列表中某个元素的所有索引,应该为其编写另一个谓词,而不使用名为allIndexesOf的cut或其他内容。

我用后继符号编写了这个谓词,它非常简洁明了:

index([V|_],V,0).
index([_|T],V,s(I)) :- index(T,V,I).
样本输出:

?- index([a,b,c,a],a,X).
X = 0 ;
X = s(s(s(0))) ;
false.

?- index(List,a,s(0)).
List = [_G1710, a|_G1714].

看起来是一个好的开始。@Aschepper是的,但我越来越疯狂,让这个小谓词工作!!!在学习prolog时,这确实是一个很好的练习。仅供参考:实现这一点的建筑谓词是
nth0
nth1
。谢谢你的回答。我可以将第一个子句替换为:indexOf([first | |,Element,Index):-first==Element,Index==0?答案是否定的。你能解释一下为什么吗?==运算符不执行统一。因此,它无法将索引实例化为0。但是,可以在第一次比较中使用它(first==元素就可以了,因为在该谓词中,两个术语都应该实例化)。当索引未实例化时,Index==0将失败。是的,这也很容易。我将使用一个迭代列表列表的过程,对于每个列表,您可以调用这个答案的过程。或者,只需发出
member(List,ListOfLists),indexOf(List,Element,Index)
它会是这样的:
indexOfInListOfLists(ListOfLists,Element,Index):-member(List,ListOfLists),indexOf(List,Element,Index)。
?- index([a,b,c,a],a,X).
X = 0 ;
X = s(s(s(0))) ;
false.

?- index(List,a,s(0)).
List = [_G1710, a|_G1714].