如何从 SWI-Prolog 中的某些查询产生最大结果的列表中找到输入?

发布于 2024-10-31 02:33:27 字数 1024 浏览 3 评论 0原文

我现在刚刚开始学习 Prolog,所以我不熟悉做大多数事情的正常方式。

本质上,我有一个从输入中给出值的规则:

ScoreFromInput(Input, Score) :- ...

我有一个输入列表,它们只是数字。我无法弄清楚如何找到产生最高分数的输入。

这就是我现在所拥有的,但我认为它会无限递归:

bestInput(BestInput) :-
    %#Bind the list of valid inputs
    legalInputs(ValidInputs),
    %# -1000 is a dummy score, it should get replaced on the first call to bestInputHelper
    bestInputHelper(ValidInputs,-1000,BestInput).

%#I think this rule should work if the first input in the list is not the best one
bestInputHelper([Input|RestOfInputs],BestScore,BestInput):-
    bestInputHelper(RestOfInputs,RestBestScore,BestInput),
    ScoreFromInput(Input,BestScore),
    RestBestScore > BestScore.

%#And this one if it is the best input
bestInputHelper([Input|RestOfInputs],BestScore,Input):-
    bestInputHelper(RestOfInputs,RestBestScore,_RestBestInput),
    ScoreFromInput(Input,BestScore),
    RestBestScore =< BestScore.

这是我到目前为止所拥有的,但我想有一种更直接的方法来做到这一点。任何帮助表示赞赏!谢谢!

I'm just picking up Prolog now, so I'm unfamiliar with the normal way of doing most things.

Essentially I have a rule which gives a value from an input:

ScoreFromInput(Input, Score) :- ...

And I have a list of inputs, which are just numbers. I'm having trouble figuring out how to find the input which yields the maximum score.

This is what I have right now, but I think it recurses infinitely:

bestInput(BestInput) :-
    %#Bind the list of valid inputs
    legalInputs(ValidInputs),
    %# -1000 is a dummy score, it should get replaced on the first call to bestInputHelper
    bestInputHelper(ValidInputs,-1000,BestInput).

%#I think this rule should work if the first input in the list is not the best one
bestInputHelper([Input|RestOfInputs],BestScore,BestInput):-
    bestInputHelper(RestOfInputs,RestBestScore,BestInput),
    ScoreFromInput(Input,BestScore),
    RestBestScore > BestScore.

%#And this one if it is the best input
bestInputHelper([Input|RestOfInputs],BestScore,Input):-
    bestInputHelper(RestOfInputs,RestBestScore,_RestBestInput),
    ScoreFromInput(Input,BestScore),
    RestBestScore =< BestScore.

This is what I have so far, but I imagine there is a much more straightforward way of doing it. Any help is appreciated! Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

画骨成沙 2024-11-07 02:33:34

一个简单的说法是,如果没有更好的输入,那么输入就是最好的:

best_input(Best) :-
    legal_inputs(Inputs),
    member(Best, Inputs),
    input_score(Best, Score),
    \+ ( member(Better, Inputs), input_score(Better, S), S > Score).

要查看您自己的代码有什么问题,请尝试使用 SWI-Prolog 的图形跟踪器:

?- gtrace, best_input(Best).

and please_use_read_names inSteadOfUnreadOnes。

A simple way to state it is that an input is best if there is no better input:

best_input(Best) :-
    legal_inputs(Inputs),
    member(Best, Inputs),
    input_score(Best, Score),
    \+ ( member(Better, Inputs), input_score(Better, S), S > Score).

To see what is wrong with your own code, try for example SWI-Prolog's graphical tracer:

?- gtrace, best_input(Best).

And please_use_readable_names inSteadOfUnreadableOnes.

沉溺在你眼里的海 2024-11-07 02:33:33

尽管 Chris 对 Prolog 不太熟悉,但他概述的方法可能比 mat 的方法更有效地找到具有最大分数的输入。像克里斯这样的方法可以线性扫描可能的输入,而不是进行二次比较。

这里 ma​​xScoreOfList/3 将返回有效输入列表的最佳项目 Z 和最佳分数 B 作为第三个参数。谓词将在空列表上失败。

maxScoreOfList(Z,B,[H|T]) :-
    scoreFromInput(H,S),
    maxScoreOfListAux(Z,B,H,S,T).

需要一个“辅助”函数,如下所示,它说明了添加一些额外参数的“技巧”,以便当到达输入列表的末尾时,输出 Z 和 B 可以绑定到找到的最佳项目和分数“所以远的”:

maxScoreOfListAux(Z,B,Z,B,[ ]).
maxScoreOfListAux(Z,B,X,S,[H|T]) :-
    scoreFromInput(H,Q),
    (   S >= Q
     -> ( Y = X, R = S )
     ;  ( Y = H, R = Q )
    ),
    maxScoreOfListAux(Z,B,Y,R,T).

Despite Chris's lack of familiarity with Prolog, the approach he outlined may be a more efficient way of finding the input with the maximum score than mat's. Instead of doing a quadratic number of comparisons, an approach like Chris's is possible that linearly scans the possible inputs.

Here maxScoreOfList/3 will return the best item Z and the best score B for a list of valid inputs as the third argument. The predicate will fail on an empty list.

maxScoreOfList(Z,B,[H|T]) :-
    scoreFromInput(H,S),
    maxScoreOfListAux(Z,B,H,S,T).

A "helper" function is needed as follows, which illustrates the "trick" of adding some extra arguments so that when the end of the input list is reached, the outputs Z and B can be bound to the best item and score found "so far":

maxScoreOfListAux(Z,B,Z,B,[ ]).
maxScoreOfListAux(Z,B,X,S,[H|T]) :-
    scoreFromInput(H,Q),
    (   S >= Q
     -> ( Y = X, R = S )
     ;  ( Y = H, R = Q )
    ),
    maxScoreOfListAux(Z,B,Y,R,T).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文