首页 文章

Prolog列表谓词

提问于
浏览
0

我需要帮助三个prolog谓词来检查和操作列表 . 我是prolog的新手,非常感谢任何帮助 .

这三个谓词是:

List2 具有两次 List1 的每个元素时,

  • double_up(+List1, -List2) 为真 . 查询 double_up([a,b,c],X) 应该给 X=[a,a,b,b,c,c] . 输出列表中元素的顺序无关紧要 .
    pivot(+List1, +Pivot, -Smaller, -GreaterEq)List1 中小于 Pivot 的数字列表时
  • pivot(+List1, +Pivot, -Smaller, -GreaterEq) 为真,而 GreaterEqList1 中大于或等于 Pivot 的数字列表 .
    NewList 与输入 List 相同时,
  • fancy_replace(+List, +Takeout,+Putin, -NewList, -Count) 为真,但列表中的每个 Takeout 元素都替换为 Putin 元素 . 数量应该是被替换的外卖数量 . 例如,查询 fancy_replace([9,10,1,9,2],9,0, X, C) 应该给出 X = [0,10,1,0,2]C = 2 . 输出列表中元素的顺序无关紧要 .

2 回答

  • -1

    在Prolog中处理列表的简单模式强加了一个带有2个参数的递归谓词,匹配 - 传统上 - 输入和输出数据,以及一个基本情况,停止递归,匹配空列表 . 然后

    double_up([X|Xs], [X,X|Ys]) :- double_up(Xs, Ys).
    double_up([], []).
    

    这个谓词比需要的更为通用,因为它也适用于模式 double_up(-List1, +List2) . 例如

    ?- double_up(L,[1,1,2,2]).
    L = [1, 2].
    

    要根据需要限制其模式,我认为有必要无用地使代码复杂化,在服务谓词中移动干净循环,并留下double_up来测试参数:

    double_up(I, O) :- is_list(I), var(O), double_up_(I, O).
    double_up_([X|Xs], [X,X|Ys]) :- double_up_(Xs, Ys).
    double_up_([], []).
    

    在SWI-Prolog中,pivot / 4可能是'one-liner':

    pivot(List1, Pivot, Smaller, GreaterEq) :-
        partition(>(Pivot), List1, Smaller, GreaterEq).
    

    像分区,从库中折叠(apply)它是最后一个必需谓词的简单实现:

    fancy_replace(List, Takeout, Putin, NewList, Count) :-
        foldl(swap_n_count(Takeout, Putin), List, NewList, 0, Count).
    swap_n_count(Takeout, Putin, L, N, C0, C) :-
        (   L == Takeout
        ->  N = Putin, C is C0 + 1
        ;   N = L, C = C0
        ).
    
  • 1

    说实话,我讨厌prolog ...尽管你学习它之后很有趣也很容易

    我认为这是一个很好的参考,因为我几周前无法理解prolog的工作原理 . what does the follow prolog codes do?

    无论如何..这是你第一个问题的答案;希望你能自己解决剩下的问题:D

    double([]).
    double([H|[]], [H,H|[]]).
    double([H|T],[H,H|T1]):- double(T, T1).
    

    顺便说一句,这可能不是唯一的解决方案......但它确实有效

相关问题