Prolog,通过一些例子

Oxy*_*ron 5 recursion performance prolog

我正在学习一些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).
Run Code Online (Sandbox Code Playgroud)

我想知道的是,这可能更美观而不是实际目的.你们会以另一种方式做到这一点?为什么?这主要是为了更广泛地理解prolog中解决问题的方法:)例如,这可以在1规则中完成吗?

Fre*_*Foo 1

使用 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).
Run Code Online (Sandbox Code Playgroud)

请注意,谓词仍然是尾递归的,这意味着它不会分配额外的堆栈帧,并且除了构建列表之外还使用恒定量的内存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]
        )
    ).
Run Code Online (Sandbox Code Playgroud)