1

我有一个问题想问你一些关于代码片段的问题:

insert_pq(State, [], [State]) :- !.
insert_pq(State, [H|Tail], [State, H|Tail]) :-
    precedes(State, H).
insert_pq(State, [H|T], [H|Tnew]) :-
    insert_pq(State, T, Tnew).
precedes(X, Y) :- X < Y.  % < needs to be defined depending on problem

该函数非常清楚地将一个项目添加到优先级队列中。我遇到的问题是第一行中的切断运算符。大概每当调用到达这行代码时,这是查询的唯一可能解决方案,并且函数调用将简单地展开(或者它结束了?),没有必要回溯并搜索另一个解决方案询问。

所以这里的切断是多余的。我的推论正确吗?

4

3 回答 3

1

编译器用于消除匹配的候选谓词的特定技术称为参数索引。默认情况下,不同的 prolog 实现可能会潜在地索引不同数量的参数。

所以如果你担心一个参数是否被索引,你应该检查你正在使用索引的序言有多少参数。根据SWI 参考手册,默认情况下它只索引第一个参数。所以在你的情况下,削减实际上并不是多余的。但是,您可以明确规定应该使用谓词索引哪些参数,index/1以及hash/1在上面的链接中链接到哪些参数。

或者你可以重新排序论点,或者你可以保持削减。

于 2009-11-14T04:05:15.560 回答
1

是的,任何半体面的 Prolog 编译器都会注意到没有第二个参数是空列表的其他子句。

在第二个子句的末尾会更有用,尽管我宁愿将第二个和第三个子句组合起来并使用局部剪切(precedes(...) -> ... ; ...)。

于 2009-11-13T20:21:12.443 回答
0

是的,你是对的。即使编译器不是半体面的(SWI Prolog 肯定是这样),它可以做的最糟糕的事情是匹配第二个和第三个子句,这将立即失败。

但是,如果第二个子句匹配,则第三个子句也匹配。这是预期的行为吗?

于 2009-11-13T22:26:08.830 回答