Prolog 中的简单 nth1 谓词

发布于 2024-10-03 10:07:54 字数 119 浏览 7 评论 0原文

在 SWI Prolog 中,有一个谓词可以查找名为 nth1 的列表中的第 n 个项目。我想实现我自己的谓词版本,但如果您查看清单(nth1)代码,SWI 的版本会非常复杂。有更简单的方法吗?

谢谢 :)。

With SWI Prolog, there's a predicate that finds the nth item in a list called nth1. I want to implement my own version of the predicate but SWI's is so complicated if you look at the listing(nth1) code. Is there a simpler way of doing it?

Thank you :).

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

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

发布评论

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

评论(3

绅士风度i 2024-10-10 10:07:54

考虑对一般(可逆)整数运算使用有限域约束:

:- use_module(library(clpfd)).

nth1(1, [E|_], E).
nth1(N, [_|Xs], E) :-
        N #> 1,
        N #= N1 + 1,
        nth1(N1, Xs, E).

Consider using finite domain constraints for general (reversible) integer arithmetic:

:- use_module(library(clpfd)).

nth1(1, [E|_], E).
nth1(N, [_|Xs], E) :-
        N #> 1,
        N #= N1 + 1,
        nth1(N1, Xs, E).
迟月 2024-10-10 10:07:54

我并不是故意要自相矛盾或者让别人来真正做我的工作;我只是想要一些建议,抱歉没有说得更清楚。

我现在已经自己实现了它,但是你们能建议改进或更好的方法吗?我经常发现自己在 Prolog 中做的事情是编写一个带有一个或一组计数器的谓词,并使用较少参数的谓词来调用带有额外参数的子句。这通常最终会产生相当多的代码。不管怎样,这是我刚刚完成的实现:

item_at( N, L, Item ) :-
    item_at( N, 0, L, Item ).   
item_at( N, Count, [H|_], Item ) :-
    CountNew is Count + 1,
    CountNew = N,
    Item = H.
item_at( N, Count, [_|T], Item ) :-
    CountNew is Count + 1,
    item_at( N, CountNew, T, Item ).

有什么意见吗?谢谢 :)。用法:

?- item_at(3,[a,b,c,d,e],Item).
Item = c ;

I didn't mean to be contradictory or get someone else to do my work actually; I just wanted some advice, sorry for not being clearer.

I've implemented it myself now but could you guys possibly suggest improvements or better ways of doing it? What I often find myself doing in Prolog is writing a predicate with say a counter or set of counters and getting a predicate with fewer arguments to call the clauses with extra arguments. This often ends up producing quite a bit of code. Anyway, here's my implementation I just did:

item_at( N, L, Item ) :-
    item_at( N, 0, L, Item ).   
item_at( N, Count, [H|_], Item ) :-
    CountNew is Count + 1,
    CountNew = N,
    Item = H.
item_at( N, Count, [_|T], Item ) :-
    CountNew is Count + 1,
    item_at( N, CountNew, T, Item ).

Any comments? Thanks :). Usage:

?- item_at(3,[a,b,c,d,e],Item).
Item = c ;
烟酉 2024-10-10 10:07:54

SWI 代码有点复杂,因为谓词可用于从变量索引生成:

?- nth1(Idx,[a,b,c],X).
Idx = 1,
X = a ;
Idx = 2,
X = b ;
Idx = 3,
X = c ;
false.

如果您不想要这种行为,可以根据 nth0 轻松实现 nth1/3

nth1(Idx,List,X) :-
    Idx0 is Idx-1,
    nth0(Idx0,List,X).

编辑:也可以不用 nth0 只需几行代码即可完成:

nth1(1,[X|_],X) :- !.
nth1(Idx,[_|List],X) :-
    Idx > 1,
    Idx1 is Idx-1,
    nth1(Idx1,List,X).

The SWI code is a bit complex because the predicate can be used to generate from a variable index:

?- nth1(Idx,[a,b,c],X).
Idx = 1,
X = a ;
Idx = 2,
X = b ;
Idx = 3,
X = c ;
false.

If you don't want that behavior, nth1/3 can be implemented easily in terms of nth0:

nth1(Idx,List,X) :-
    Idx0 is Idx-1,
    nth0(Idx0,List,X).

Edit: it's also possible to do without nth0 in just a few lines of code:

nth1(1,[X|_],X) :- !.
nth1(Idx,[_|List],X) :-
    Idx > 1,
    Idx1 is Idx-1,
    nth1(Idx1,List,X).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文