プログラムは、多くの異なる問題を1つの述語に結合します。それらを少し分けてみましょう。また、同じ要素を含む2つ以上の要素の最大サブリストを検索していると仮定します。
必要なものの概算から始めましょう:サブリストの識別。これが広すぎることを心配しないでください。後で改良します。この目的のためにDCGを使用します。非終端記号seq//1
は、任意のシーケンスを表します。
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
これは非常に便利な非終端記号です!
?-フレーズ((seq(プレフィックス)、seq(サブリスト)、seq(ポストフィックス))、
[a、a、b、2,2,2、a + 1、a + 1、s(1,2)])。
プレフィックス=サブリスト、サブリスト= []、
接尾辞=[a、a、b、2,2,2、a + 1、a + 1、s(1,2)];
プレフィックス=[]、
サブリスト= "a"、
接尾辞=[a、b、2,2,2、a + 1、a + 1、s(1,2)]..。
両方の答えは期待されていません。長さが2以上のサブリストのみが必要なので、その定義を少し制限する必要があります。Sublist
たとえば、少なくとも2つの要素が含まれている必要があることを要求します。それはSublist = [_,_|_]
です。
?-サブリスト= [_、_ | _]、
フレーズ((seq(プレフィックス)、seq(サブリスト)、seq(ポストフィックス))、
[a、a、b、2,2,2、a + 1、a + 1、s(1,2)])。
サブリスト="aa"、
プレフィックス=[]、
後置=[b、2,2,2、a + 1、a + 1、s(1,2)];
サブリスト="aab"、
プレフィックス=[]、
接尾辞=[2,2,2、a + 1、a + 1、s(1,2)]..。
最初の答えは、私たちが探しているサブリストを示しています。しかし、2番目はまだ正しくありません。サブリストのすべての要素が等しくなければなりません。最も簡単な方法は、以下を使用することmaplist/2
です。
?-maplist(=(_)、Es)。
Es = [];
Es = [_G221];
Es = [_G221、_G221];
Es = [_G221、_G221、_G221]
その要件を述べることができる場所がいくつかあります。私はそれを可能な限り早い場所に置きます:
?-サブリスト= [_、_ | _]、
フレーズ((seq(プレフィックス)、
seq(Sublist)、{maplist(=(_)、Sublist)}、
seq(Postfix))、
[a、a、b、2,2,2、a + 1、a + 1、s(1,2)])。
サブリスト="aa"、
プレフィックス=[]、
後置=[b、2,2,2、a + 1、a + 1、s(1,2)];
サブリスト=[2,2]、
プレフィックス="aab"、
接尾辞=[2、a + 1、a + 1、s(1,2)];
サブリスト=[2,2,2]、
プレフィックス="aab"、
接尾辞=[a+ 1、a + 1、s(1,2)];
サブリスト=[2,2]、
プレフィックス=[a、a、b、2]、
接尾辞=[a+ 1、a + 1、s(1,2)];
サブリスト=[a+ 1、a + 1]、
プレフィックス=[a、a、b、2,2,2]、
後置=[s(1,2)];
false。
そのため、すべてのサブリストに同じ要素が含まれるようになりました。残念ながら、両方[2,2]
と[2,2,2]
サブリストを取得します。最大のサブリストのみが必要です。では、最大サブリストとはどのように説明できるでしょうか。
1つの方法は、サブリストの前を確認することです。サブリストにまったく同じ要素があってはなりません。したがって、前に何も(イプシロン)ないか、または私たちとは異なる要素で終わるシーケンスがあります。
difel(_E,[]).
difel(E, Es) :- dif(E,F), phrase((seq(_), [F]), Es).
?-サブリスト= [_、_ | _]、
フレーズ((seq(プレフィックス)、{difel(E、プレフィックス)}、
seq(Sublist)、{maplist(=(E)、Sublist)}、
seq(Postfix))、
[a、a、b、2,2,2、a + 1、a + 1、s(1,2)])。
サブリスト="aa"、
プレフィックス=[]、
E = a、
後置=[b、2,2,2、a + 1、a + 1、s(1,2)];
サブリスト=[2,2]、
プレフィックス="aab"、
E = 2、
接尾辞=[2、a + 1、a + 1、s(1,2)];
サブリスト=[2,2,2]、
プレフィックス="aab"、
E = 2、
接尾辞=[a+ 1、a + 1、s(1,2)];
サブリスト=[a+ 1、a + 1]、
プレフィックス=[a、a、b、2,2,2]、
E = a + 1、
後置=[s(1,2)];
false。
間違った答えが1つ少なくなります。最後にまだ1つ潜んでいます。
?-サブリスト= [_、_ | _]、
フレーズ((seq(プレフィックス)、{difel(E、プレフィックス)}、
seq(Sublist)、{maplist(=(E)、Sublist)}、
([] | [F]、{dif(E、F)}、seq(_)))、
[a、a、b、2,2,2、a + 1、a + 1、s(1,2)])。
サブリスト="aa"、
プレフィックス=[]、
E = a、
F = b;
サブリスト=[2,2,2]、
プレフィックス="aab"、
E = 2、
F = a + 1;
サブリスト=[a+ 1、a + 1]、
プレフィックス=[a、a、b、2,2,2]、
E = a + 1、
F = s(1,2);
false。
それはあなたが望んでいたものではありません:あなたは単に長さを望んでいました。このために、を追加しlength([_|Prefix],I), length(Sublist,Len)
ます。
したがって、最終的な定義は次のとおりです。
高原(Xs、I、Len):-
サブリスト=[_、_ | _]、
フレーズ((seq(プレフィックス)、{difel(E、プレフィックス)}、
seq(Sublist)、{maplist(=(E)、Sublist)}、
([] | [F]、{dif(E、F)}、seq(_)))、
Xs)、
長さ([_ |プレフィックス]、I)、
length(Sublist、Len)。