2017-11-19 19 views
4

プロローグの新機能で、要素を任意の位置にリストに挿入できるすべてのオプションを与える述語を作成しようとしました。 例:プロローグリストの任意の位置に挿入

インins(a, [b,c], R).を与える必要があります:それはありませんが、その後、 'グローバルスタック外' というエラーになる

R = [a,b,c] 
R = [b,a,c] 
R = [b,c,a] 

。これをより決定論的にし、結果を与え、実行する方法はありますか?それが逆に実行されると、すなわち。 ins(X、Y、[a、b、c])である。期待される結果が得られ、それが完了したことを示すfalseと表示されます。 コード:ここで

app([],L,L). 
app([H|T],L2,[H|L]) :- 
    app(T,L2,L). 

ins(E, List, R) :- 
    R = R1, 
    app(R2, R3, R1), 
    app([E], R4, R3), 
    app(R2, R4, List). 

はオンラインコンパイラでコードを実行するためのリンクです、どれ役立つだろう SWISHは(これも私がインを使用することを望む方法の例がありますが、インは、今問題となっています)ありがとう!

答えて

3

これはどのように悪いことに気付きましたか?まず、Prologは非常に素晴らしく、ダンディーであり、それがいかにスマートであるかを示しました。後でそれがあなたに打たれました:購入。もっと。 RAM。今すぐ!

Prologが正面を向いていれば良いとは思いませんか?回答を表示する前に?

さて、Prologにこれを強制することができます。そのようなクエリの最後にfalseを追加します。

 
?- ins(a, [b,c], R), false. 
ERROR: Out of global stack 

そして、あなたはあなたの残りのプログラムで行うことができます同じ:単に残りのプログラムがまだループまたは容量が不足することfalseなどを追加します。私たちはそのループを取り除くために、残りの可視部分で何かを変更する必要があることを意味し、次の最小限の

 
app([],L,L) :- false. 
app([H|T],L2,[H|L]) :- 
    app(T,L2,L), false. 

ins(E, List, R) :- 
    R = R1, 
    app(R2, R3, R1), false, 
    app([E], R4, R3), 
    app(R2, R4, List). 

?- ins(a, [b,c], R), false. 

を思い付きました。言い換えれば、目に見える部分が修正されていない限り、エラーは持続します—が保証されます!

非終了の理由を理解するには、この技術の詳細については

はすぐに修正が最後に最初のアプリ/ 3ゴールを入れることであろう参照してください。


しかし、他にも何かがあります:あなたが推測することが困難なすべての種類の変数を使用しました。もっと統一された計画に固執するかもしれない。また、app/3を使用して[A]を追加する必要はありません。あなたは実際には2つのapp/3の目標しか必要としません。これが与える

ins(Elem, In, Lst_Out) :- 
    setof(Out, select(Elem, Out, In), Lst_Out). 

SETOF

?- select(a, Out, [b,c]). 
Out = [a, b, c] ; 
Out = [b, a, c] ; 
Out = [b, c, a] ; 
false. 

はあなたが呼ばれる別の非常に便利な述語とそれを使用することができます。

0

Prologはを選択すると呼ばれる興味深い述語を持って

?- ins(a, [b,c], Out). 
Out = [[a, b, c], [b, a, c], [b, c, a]]. 
1
ここ

は、この述語の単純な実装です:

ins(X, [], [X]). 
ins(X, [H|T], [X,H|T]). 
ins(X, [H|T], [H|T2]) :- 
    ins(X, T, T2). 

それはあなたがそれを期待する方向に動作します:

?- ins(a, [b,c], R). 
R = [a, b, c] ; 
R = [b, a, c] ; 
R = [b, c, a] ; 
false. 

?- ins(a, L, [a,b,c]). 
L = [b, c] ; 
false. 

?- ins(X, [b,c], [a,b,c]). 
X = a ; 
false. 

?- ins(X, L, [a,b,c]). 
X = a, 
L = [b, c] ; 
X = b, 
L = [a, c] ; 
X = c, 
L = [a, b] ; 
false. 

?- ins(a, X, Y). 
X = [], 
Y = [a] ; 
X = [_5312|_5314], 
Y = [a, _5312|_5314] ; 
X = [_5312], 
Y = [_5312, a] ; 
X = [_5312, _5324|_5326], 
Y = [_5312, a, _5324|_5326] ; 
… 
+0

なぜこれほど多くの事実? – false

+0

@false実際には、両方の事実を 'ins(X、L、[X | L]) 'に融合することができます。両方のバージョンはまだ 'ins(a、X、Y)'に問題があります(可能性のあるすべてのケースを列挙しません)。 – Fatalize

関連する問題