1

宣言的推論に参加するにはいくつかの問題があります...だから、私の推論が正しいかどうか、何か間違っているかどうか、または何かが足りないかどうかを尋ねるためにここにいます...

次の問題があります:リストの要素を反転する Prolog プログラムを作成する

たとえば、次のようなものを呼び出す場合:

myreverse([a,b,c,d,e],X)。X=[e,d,c,b,a] を取得する必要があります

私は次の解決策を持っています:

naiverev([],[]).  
naiverev([H|T],R):- naiverev(T,RevT),
                    append(RevT,[H],R).

これは私の解釈です:

空のリストの逆は空のリストであるという事実があります。

最初のリストが空でない場合は、真ではないという事実とそうでないという事実が一致するため、次のルールに進みます。

ルールは次のように述べています: リスト R がリスト [H|T] の逆数であることを証明するプログラム

次の方法で、論理的な意味を右から左に読むことができます。

naivrev(T, RevT) AND append(RevT, [H], R) ---> naivrev([H|T],R) が TRUE の場合

したがって、(ルールの本文では) 「関数」naivrev(T,RevT)は、RevT が T の逆数の場合に TRUE を応答し、それ以外の場合は FALSE を応答すると想定しています。

同時に、**append(RevT,[H],R)は、R が [H|RevT] の場合に TRUE を応答し、それ以外の場合は FALSE を応答すると想定しています。

次に、ルール本体の両方の部分が TRUE の場合、プログラムは HEAD が TRUE であると推測できます (この場合、R は [H|T] の逆数です)。

この推論は良いですか、それとも何か不足していますか?

4

1 に答える 1

2

最後の2回のように、あなたは再びPrologの計算エンジンを純粋に宣言型の読みと混ぜ合わせました。手続き的に「ルールが一致しないので先に進んでください」などと言うときはいつでも、ロジックではなく、何が起こっているのかを説明するためにPrologのアルゴリズムを呼び出しています。しかし、残りの部分が以前よりもはるかに近くなっているため、あなたは良くなっています。

ルール1:空のリストの逆は空のリストです。(あなたが持っているのと同じです。)

ルール2:[H | T]の逆は、リスト[H]に追加されるRevTと呼ばれるTの逆です。

もちろん、これを機能させるのは、Prologがルール1を試行し、一致しない場合はルール2を試行し、結果を再帰的に構築することです(おそらくご存知のとおり、非常に非効率的な方法で)。しかし、ルールをチェックし、それらの間で選択し、そのプロセスがどのように実行されるかというこの「成功」は、Prologが宣言的または論理的なステートメントに追加するものです。

論理的含意の読み方は正しいです。naiverev(T、RevT)が真で、append(RevT、[H]、R)が真の場合、naiverev([H | T]、R)は真です。これは、前の質問で@falseが説明したのと同じです。したがって、間違いなく取得し始めていると思います。体が真実であり、頭が真実であるというあなたの発言は的を射ています。

とても良い仕事です、あなたはそれを手に入れているようです。:)

于 2013-03-20T17:55:28.653 に答える