0

リストをチェックして操作するための 3 つのプロローグ述語について、助けが必要です。私はプロローグが初めてで、どんな助けでも大歓迎です。

3 つの述部は次のとおりです。

  • double_up(+List1, -List2)List2は、各要素がList12 倍の場合に true です。クエリdouble_up([a,b,c],X)X=[a,a,b,b,c,c]. 出力リスト内の要素の順序は重要ではありません。
  • pivot(+List1, +Pivot, -Smaller, -GreaterEq)がより小さいSmallerの数のリストであり、 がより大きいか等しい の数のリストである場合、 は真です。List1PivotGreaterEqList1Pivot
  • fancy_replace(+List, +Takeout,+Putin, -NewList, -Count)NewListがinput と同じリストの場合は true ですが、リスト内のListTakeout要素は要素に置き換えられPutinます。Count は、置き換えられた Takeout の数である必要があります。たとえば、クエリは とfancy_replace([9,10,1,9,2],9,0, X, C)を与える必要がX = [0,10,1,0,2]ありC = 2ます。出力リスト内の要素の順序は重要ではありません。
4

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 が「ワンライナー」になる可能性があります。

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

partition, foldl from library( 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
    ).
于 2013-04-23T06:49:46.960 に答える
-1

正直なところ、私はプロローグが嫌いです... 覚えた後は楽しくて簡単ですが

数週間前にプロローグがどのように機能するかを理解するのに苦労していたので、これは良い参考になると思います. 次のプロローグ コードは何をしますか?

とにかく..これが最初の問題の答えです。うまくいけば、残りは自分で解決できます:D

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

ところで、これが唯一の解決策ではないかもしれません...しかし、それは機能します

于 2013-04-23T04:17:40.337 に答える