【问题标题】:prolog cut off in methodprolog 在方法中被截断
【发布时间】:2009-11-13 16:17:57
【问题描述】:

我有一个问题想问你一些关于代码 sn-p 的问题:

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

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

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

【问题讨论】:

    标签: prolog logic


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      或者你可以重新排序参数,或者你可以保持剪切。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 2016-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-04
          • 2023-03-23
          • 1970-01-01
          • 1970-01-01
          • 2021-11-30
          相关资源
          最近更新 更多