Prolog列表谓词

时间:2013-04-23 03:43:44

标签: list prolog

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

这三个谓词是:

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

2 个答案:

答案 0 :(得分:1)

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

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

这个谓词比需要的更多 general ,因为它也可以在模式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_([], []).

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

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

就像分区一样,来自库(apply)的foldl,它是最后一个必需谓词的简单实现:

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 :(得分:-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).
顺便说一句,这可能不是唯一的解决方案......但它可以正常工作