Prolog,通过一些示例进行工作

发布于 2024-10-21 00:29:30 字数 436 浏览 1 评论 0原文

我正在学习一些 Prolog 教程(没有更好的事情可做,本周早些时候我发现我非常喜欢编程,所以我正在研究一些范例)并进行了一个练习,要求我编写一个谓词 delete_from_list/3 ,它删除列表中所有给定的事件。

我已经解决了这个问题,如下:

delete_from_list([], _, []).
delete_from_list([Ah|At], X, [Ah|Bt]) :- Ah \= X, !, delete_from_list(At, X, Bt).
delete_from_list([_|Ct], X, Bt) :- delete_from_list(Ct, X, Bt).

我想知道什么,这可能比实际目的更美观。你们会如何以另一种方式做到这一点?为什么? 这主要是为了对序言中解决问题的方法有更广泛的了解:) 例如,这可以在 1 条规则中完成吗?

I'm working through some Prolog tutorials (nothing better to do and I found out earlier this week I quite like programming, so I'm working through some paradigms) and got to an exercise asking me to write a predicate delete_from_list/3 which removes all given occurences from a list.

I've solved this as follows:

delete_from_list([], _, []).
delete_from_list([Ah|At], X, [Ah|Bt]) :- Ah \= X, !, delete_from_list(At, X, Bt).
delete_from_list([_|Ct], X, Bt) :- delete_from_list(Ct, X, Bt).

What I'm wondering though, and this might be more aesthetic than practical purpose. How would you guys do this in another way? And why?
This mostly to gain a broader understanding of ways of problem solving in prolog :)
For example, could this be done in 1 rule?

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

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

发布评论

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

评论(3

绿萝 2024-10-28 00:29:30

使用 if-then-else 可以更优雅地完成此操作(不涉及剪切):

delete_from_list([], _, []).
delete_from_list([X|Xs], Y, Result) :-
    (X = Y ->
        Result = Result0
    ;
        Result = [X|Result0]
    ),
    delete_from_list(Xs, Y, Result0).

并注意谓词仍然是 尾递归,这意味着它不会分配额外的堆栈帧,并且除了构建 Result 列表之外,还会使用恒定的内存量。

是的,它可以在一个子句中完成,但这并不漂亮:

delete_from_list(Xs, Y, Result) :-
    (Xs = [] ->
        true
    ;
        Xs = [X|Xs0],
        delete_from_list(Xs0, Y, Result0),
        (X = Y ->
            Result = Result0
        ;
            Result = [X|Result0]
        )
    ).

With an if-then-else this can be done more elegantly (no cut involved):

delete_from_list([], _, []).
delete_from_list([X|Xs], Y, Result) :-
    (X = Y ->
        Result = Result0
    ;
        Result = [X|Result0]
    ),
    delete_from_list(Xs, Y, Result0).

And note that the predicate is still tail-recursive, meaning it doesn't allocate extra stack frames and uses a constant amount of memory apart from building up the Result list.

And yes, it can be done in one clause, but it's not pretty:

delete_from_list(Xs, Y, Result) :-
    (Xs = [] ->
        true
    ;
        Xs = [X|Xs0],
        delete_from_list(Xs0, Y, Result0),
        (X = Y ->
            Result = Result0
        ;
            Result = [X|Result0]
        )
    ).
哀由 2024-10-28 00:29:30

如果我正确理解这个问题, select/3 做同样的事情

?- select(3,[1,2,3,4],X), !.
X = [1, 2, 4].

If I'm correctly understand this problem, select/3 do the same thing

?- select(3,[1,2,3,4],X), !.
X = [1, 2, 4].
梦里的微风 2024-10-28 00:29:30

这是使用removeAllFromList/4 和 累加器

removeAllFromList(List, X, ListAns) :-
    removeAllFromList(List, X, [], ListAnsReverse),
    reverse(ListAnsReverse, ListAns),!.

removeAllFromList([], _, ListAns, ListAns).
removeAllFromList([H | Tail], X, OutList, ListAns) :-
    (
    (H =\= X, append([H], OutList, OutListNew))
    ;(H = X, OutListNew = OutList)
    ),
    removeAllFromList(Tail, X, OutListNew, ListAns).

Here is removeAllFromList/3 predicate using removeAllFromList/4 with accumulator

removeAllFromList(List, X, ListAns) :-
    removeAllFromList(List, X, [], ListAnsReverse),
    reverse(ListAnsReverse, ListAns),!.

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