私はこの非常に単純な問題を抱えています:2つの文字列を連結し、次のように機能する、追加のProlog関数を実装するPrologプログラムを作成します。
- append([a、b]、[c、d]、X)。---> X = [a、b、c、d]
- append([a、b]、X、[a、b、c、d])。---> X = [c、d]
- append([a、b]、[X、d]、[a、b、c、d])。---> X = c
- append(X、Y、[a、b、c、d])。---> X=[]およびY=[a、b、c、d)
したがって、次の2つの解決策がありますが、宣言型の解釈が正しいかどうかはわかりません。
1)解決策1:
myappend1([],L,L).
myappend1([X|L1],L2,[X|L3]) :- myappend1(L1,L2,L3).
私はそれを次のように宣言的な方法で読むことができると思います:
事実は次のように述べています。最初のリスト(L1)が空で、2番目のリスト(L2)が空でない場合、L1*L2の連結がL2であることはTRUEです。
それが真実でないという事実は、最初のリストが空ではないことを意味します。したがって、最初のリストと2番目のリストの連結は、2番目のリストであるということは真実ではありません。
したがって、最初のリストをL1、2番目のリストをL2、3番目のリストをL3と呼ぶと、L3がL1とL2の連結である場合、ルールはTRUEと応答し、それ以外の場合はfalseと応答します。
このルールの宣言的な意味は次のとおりだと思います。ルールの本体が真の場合、ルールの先頭は真です。
- 頭の中で、L1リストとL3リストから最初のX要素を抽出します(一致する場合は統合を試みます。一致しない場合は、3番目のリストが最初と2番目のリストの連結ではないことを意味します)
- 本文では、X要素のない最初のリスト、2番目のリスト、およびL3リスト(連結を表す)の関数を呼び出します。
myappend1([]、L、L)という事実が実証されたベースケースに到達したとき。つまり、プログラムは前の過去にバックトラックを実行し、最初のリストのX要素が3番目のリストのX要素と統合されているため、この計算パスもTRUEであり、最初のアサーションに到達するまで戻ります。
これは正しい宣言型の解釈ですか?
2)2番目の解決策:
myappend2([],L,L).
myappend2(L1,L2,L3) :- L1=[X|T], % Dimostra questo predicato AND
L3=[X|L4], % Dimostra questo predicato AND
myappend2(T,L2,L4). % Dimostra questa funzione
前のソリューションと同様に、事実は単純に次のように述べています。最初のリスト(L1)が空で、2番目のリスト(L2)が空でない場合、L1*L2の連結がL2であることはTRUEです。
それが真実でないという事実は、最初のリストが空ではないことを意味します。したがって、最初のリストと2番目のリストの連結は、2番目のリストであるということは真実ではありません。
事実が真でない場合、Prologはルールを呼び出し、このルールは次のことを意味します。ルールの本体が真の場合、ルールの先頭は真です。
この場合、私はそれを次のように読むことができます:
L1とL2の連結はL3であり、次のことが当てはまる場合はTRUEです。
- L1の現在の最初のX要素は、連結リストの現在の最初の要素と統合され、myappend2は最初のサブリストL2と3番目のサブリストで呼び出されます。
それが正しいか?
私にとって、宣言的な方法で推論するのはとても難しいです:-(