5

質問

論理的純度に関する質問があります。

このプログラムは純粋ですか?

when(ground(X), X > 2).

コンテキストに関する [irrelevant] の詳細

良い終了特性を持つ純粋な述語を書こうとしています。たとえばlist_length/2、リストとその長さの関係を記述する述語を書きたいとします。組み込みの predicate と同じ終了動作を実現したいlength/2

私の質問は、次の述語が純粋かどうかを調べようとしています。

list_length([], 0).
list_length([_|Tail], N):-
    when(ground(N), (N > 0, N1 is N - 1)),
    when(ground(N1), N is N1 + 1),
    list_length(Tail, N1).

で目標を達成できます...

:- use_module(library(clpfd)).
:- set_prolog_flag(clpfd_monotonic, true).

list_length([], 0).
list_length([_|Tail], N):-
    ?(N) #> 0,
    ?(N1) #= ?(N) - 1,
    list_length(Tail, N1).

... またはvar/1、 、nonvar/1andを使用できますが、述語が純粋であることを証明するの!/0困難です。

list_length([],0).
list_length([_|Tail], N):-
    nonvar(N), !,
    N > 0,
    N1 is N - 1,
    list_length(Tail, N1).
list_length([_|Tail], N):-
    list_length(Tail, N1),
    N is N1 + 1.
4

1 に答える 1

4

when/2 と ground/1 の論理純度

ground/1と同じくらい不純なISO 組み込みがあることに注意してくださいnonvar/1。しかし、あなたはむしろ の条件について話しているようですwhen/2。実際、 の受け入れられた条件when/2は、可能な限り純粋です。したがって、これは だけに当てはまるわけではありませんground/1

このプログラムは純粋ですか?

when(ground(X), X > 2).

はい、現在の純粋な意味で。つまり、library(clpfd)純粋と見なすのとまったく同じ意味です。ロジック プログラミングと Prolog のごく初期の 1970 年代などでは、純粋なプログラムは、真であれば成功し、偽であれば失敗する唯一のものでした。他には何もありません。

ただし、今日では、サイレント エラーの代わりにタイプ エラーなどのISO エラーが発行されることを認めています。実際、これは実用的な観点からははるかに理にかなっています。考えてみてくださいX = non_number, when(ground(X), X > 2 )。このエラー システムは、比較的遅れて Prolog に導入されたことに注意してください。

Prolog Iはビルトインのエラーを明示的に報告しましたが、その後の DEC10-Prolog (1978 年、1982 年など) や C-Prolog には、信頼できるエラー報告システムが含まれていませんでした。代わりに、メッセージが出力され、述語が失敗したため、エラーと論理的誤りが混同されました。warningこの時点から、Prolog フラグunknown(ISO/IEC 13211-1:1995 の 7.11.2.4)の値が残っているため、未定義の述語を実行しようとすると警告が出力されて失敗します。

それで、キャッチはどこですか?検討

?- when(ground(X), X> 2), when(ground(X), X < 2).
when(ground(X), X>2),
when(ground(X), X<2).

これらwhen/2の s は、完全に正しいものですが、答えとして矛盾を生み出すことに大きく貢献しています。結局のところ、上記は次のとおりです。

はい、まったく同じクエリが真であれば、クエリは真です。

これを SICStus や SWI と比較してくださいlibrary(clpfd):

| ?- X #> 2, X #< 2.
no

したがってlibrary(clpfd)、この不一致を検出できwhen/2ますが、引数が根拠になるまで待つ必要があります。

このような条件付きの回答を得ることは、しばしば非常に混乱を招きます。実際、多くの状況では、幾分きれいな when よりも平凡なインスタンス化エラーを好む人が多くいます。

これに対する明確な一般的な答えはありません。結局、制約に関する多くの興味深い理論は決定不能です。はい、非常に無害に見えるため、library(clpfd)すでに決定不可能な問題を定式化できます。したがって、解決策を含まないそのような条件付きの回答と一緒に暮らす必要があります。

ただし、純粋な無条件のソリューションを取得するか、実際の失敗を取得すると、これが保持されることがわかります。

list_length/2

使用する定義は、プロローグのプロローグで合意さlibrary(clpfd)れたものよりも、実際には終了に関してわずかに優れています。検討:

?- N in 1..3, list_length(L, N).

また、ゴールlength(L,L)は非常に自然な形で型エラーを生成します。つまり、明示的なテストはありません。

使用しているバージョンには、失敗するが成功するwhen/2など、「自然な」不規則性があります。それ以外の場合は、構成だけで問題ないようです。length(L,0+0)length(L,1+0)


1) 最も古い説明は、G. Battani、H. Meloni の 9 ページにあります。Interpréteur du langage de programmation Prolog. Rapport de DEA d'informatique appliquée、1973 年。そこでは、組み込みエラーが解決されなかった目標に置き換えられました。II-3-6 a, p.13 の現在の用語 plus/3 では、現在のシステムではfreeze/2:

plus(X, Y, Z) :-
   (  integer(X), integer(Y), ( var(Z) ; integer(Z) )
   -> Z is X+Y
   ;  freeze(_,erreur(plus(X,Y,Z)))
   ).

だからplus/3「多方向」ではありませんでした。

于 2015-01-17T17:29:21.870 に答える