1


0

GNU Prolog-ループでリストを作成する

「ループ」を使用して新しいリストを作成する必要があります。 基本的に、明示的に再帰を使用することはできないため、リストのリストを調べるために追加を使用しています。

要素を取得できます。 問題は、この要素をチェックする必要があることです。何か真である場合、リストに戻す必要がある別の要素を返します。 正しくチェックし、正しく変更します。

私が抱えている問題は、完全に新しいリストを作成する方法です。

だから、もし私が持っていたら

[[1,1,1],[2,6,2],[3,3,3]]

各要素について説明します。 私が6に着いたと言って、それは変わります。 だから私はそのような新しいリストを作成する必要があります、

[[1,1,1],[2,10,2],[3,3,3]].

現在、私の主な問題は、各行を作成することです。 各行を作成できる場合、リストのリストを作成できます。

したがって、これをもう少し詳しく説明するために、[1,1,1]について心配するだけにします。

newlistに新しい要素を追加しながら、各要素を調べます。 新しいリストは[1,1,1]になりました

私はこれを持っています:

set(Row,Col,Bin,TheEntry,Bout) :-
 append(ListLeft, [R|_], Bin),
  append(ListLeft2, [C|_], R),
   length(ListLeft, LenR),
   length(ListLeft2,LenC),
   CurrRow is LenR + 1,
   CurrCol is LenC + 1,
   getChar(C, Row, Col, CurrRow, CurrCol,TheEntry, NewC),
            appendhere?.

NewCから返された文字で新しいリストを作成する必要があります。 これを行う方法がわからない。

何か手がかりはありますか?

ありがとう。

2 回答


2


リストのリストからアイテムを抽出するために「append / 3」を使用する方法についてのアイデアを与えるには、「replace / 2」と呼ばれる次の述語を考えてください。

replace(In, Out) :-
    append(LL, [L|RL], In),
    append(LE, [E|RE], L),
    replaceElement(E, NewE), !,
    append(LE, [NewE|RE], NewL),
    append(LL, [NewL|RL], Out).
replace(In, In).

この_non-recursive_述語は、 In`putとして、リストのリストとバックトラックを取り、内部リスト L`内で replaceElement / 2`で置換できる要素 E`を見つけます。その場合、最初に内部リストを作成することで置き換えられ( NewL)、その後、新しい外部リストの作成でこの新しいリストを使用し(` Out`)、結果として。

*注意*これは単に、 append / 3`を使用して、リストのリストを分解し、必要に応じて、再帰ではなく、バックトラックを介して個々の要素を取得する方法を示すためのものです。 要素 `E`が replaceElement / 3`を介して NewE`で置き換え可能になると、図のように append / 3`を使用してリストの構築に再び使用されます。

また、この_suggestion_(これは最終的な答えではなく、あなたを助けることを目的としています)が、内部リスト内の単一の要素(存在する場合)のみを置き換えることにも注意してください。 replace / 2`または類似の_このテクニックを使用して、単一の呼び出しで入力リストの複数の置換を行いたい場合、ほぼ確実に再帰定義、または assert`を介してグローバルデータベースを使用する機能が必要になります。 他の誰かが定義を反例として提供できるなら、私は修正されてうれしいです。

この例では、述語「replace / 2」と、たとえば次の事実があります。

replaceElement(6, 10).

以下を実行すると、必要な動作が得られます。

1 ?- replace([[1,1,1],[2,6,2],[3,3,3]], Out).
Out = [[1, 1, 1], [2, 10, 2], [3, 3, 3]] ;
false.

カット( )を使用できない場合は省略してもかまいませんが、2番目の句 `replace(In、In)`により、 `replace / 2`のすべての呼び出しが少なくとも1回バックトラックして、入力リストに戻ります。 この動作が望ましくない場合、この2番目の句を省略すると、置換が行われない場合に `replace / 2`が完全に失敗します。


0


再帰を使用できず、バックトラッキングでそれを行う必要がある場合は、次のようにする必要があります:ビンはリストのリストである(各項目は完全な行)〜入力ビンを3つの部分に分割する(「左」行のリスト、行、および残りの行のリスト)。 これはappend / 3とappend(Left、[Item | Rest]、Rows)のようなものを使用して行うことができます〜「左」行の長さを取得します〜「is」演算子を使用して長さをテストし、左リストの有無を確認します行-1アイテム〜同じことを行いますが、今はアイテムを使用します。つまり、 3つの部分に分割します(LeftColums、ColumItem、Rest)〜必要な列に対して長さをテストします〜これで、変更する項目があるので、2つの追加(1つは選択した行を再構築し、出力リストを再構築する別の)。

したがって、コードから名前のない変数(_)を使用することはありません。 その代わりに、名前付き変数を使用して、アイテムを変更した新しいリストを再構築する必要があります。