73

プロローグで if を実行する方法はありますか。たとえば、変数が 0 の場合、いくつかのアクションを実行します (端末にテキストを書き込む)。else は必要ありませんが、if のドキュメントが見つかりません。

4

10 に答える 10

107

はい、ISOPrologにはそのような制御構造があり->ます。次のように使用します。

( condition -> then_clause ; else_clause )

else-if-clausesのチェーンを使用する例を次に示します。

(   X < 0 ->
    writeln('X is negative.  That's weird!  Failing now.'),
    fail
;   X =:= 0 ->
    writeln('X is zero.')
;   writeln('X is positive.')
)

else-clauseを省略した場合、条件が失敗すると、ifステートメント全体が失敗することに注意してください。したがって、else-clauseを常に含めることをお勧めします(たとえそれがちょうどであってもtrue)。

于 2011-06-11T08:25:59.807 に答える
54

標準のプロローグ述語がこれを行います。

   isfive(5). 

5 で呼び出した場合は true と評価され、それ以外で実行した場合は失敗 (false を返す) と評価されます。等しくない場合は \= を使用します

isNotEqual(A,B):- A\=B.

技術的には統一ではありませんが、等しくないことに似ています。

Learn Prolog Now は、プロローグを学習するための優れた Web サイトです。

編集:別の例を追加するには。

isEqual(A,A). 
于 2010-05-17T14:13:44.237 に答える
31

プロローグの述語「統一」 -

だから、命令語で私は書くだろう

function bazoo(integer foo)
{
   if(foo == 5)
       doSomething();
   else
       doSomeOtherThing();
}

プロローグで私は書くだろう

bazoo(5) :-  doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.

両方のスタイルを理解すると、実際にはより明確になります。
「foo が 5 の特殊なケースでは
バズーです」「foo が 5 でない通常のケースではバズーです」

于 2011-12-09T22:13:40.737 に答える
16

まず、古典的な一階論理を思い出してみましょう。

" If P then Q else R" は "(P and Q) or (non_P and R)" と同等です。


Prologでは、そのような「if-then-else」をどのように表現できますか?

次の具体例を見てみましょう。

Xが list のメンバーである場合は、[1,2] それ 以外の場合はX等しい2 ですX4

上記のパターン (" If P then Q else R") にマッチできるのは ...

  • 状態Plist_member([1,2],X)
  • 否定状態non_Pnon_member([1,2],X)
  • 結果QX=2、そして
  • 代替品RはありませんX=4

リストの (非) メンバーシップを純粋な方法で表現するには、次のように定義します。

list_memberd([E|Es],X) :-
   ( E = X
   ; 差分(E,X),
      list_memberd(Es,X)
   )。

非メンバー (Es、X) :-
   maplist(dif(X),Es)。

Prolog での「if-then-else」のさまざまな表現方法を見てみましょう。

  1. (P,Q ; non_P,R)

    ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4)。
    X = 2; X = 4。
    ?- X=2, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2.
    X = 2 ; 偽。
    ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2.
    X = 2 ; 偽。
    ?- X=4, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4.
    X = 4。
    ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4.
    X = 4。
    

    正しさスコア 5/5。効率スコア 3/5。

  2. (P -> Q ; R)

    ?- (list_memberd([1,2],X) -> X=2 ; X=4)。
    。% 違う
    ?- X=2, (list_memberd([1,2],X) -> X=2 ; X=4), X=2.
    X = 2。
    ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=2.
    。% 違う
    ?- X=4, (list_memberd([1,2],X) -> X=2 ; X=4), X=4.
    X = 4。
    ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=4.
    。% 違う
    

    正しさスコア 2/5。効率スコア 2/5。

  3. (P *-> Q ; R)

    ?- (list_memberd([1,2],X) *-> X=2 ; X=4)。
    X = 2 ; 偽。% 違う
    ?- X=2, (list_memberd([1,2],X) *-> X=2 ; X=4), X=2.
    X = 2 ; 偽。
    ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=2.
    X = 2 ; 偽。
    ?- X=4, (list_memberd([1,2],X) *-> X=2 ; X=4), X=4.
    X = 4。
    ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=4.
    。% 違う
    

    正解率 3/5。効率スコア 1/5。


(暫定) 要約:

  1. (P,Q ; non_P,R)は正しいですが、 の個別の実装が必要ですnon_P

  2. (P -> Q ; R)インスタンス化が不十分な場合、宣言的セマンティクスが失われます。

  3. (P *-> Q ; R)より「少ない」不完全です(P -> Q ; R)が、それでも同様の問題があります。


幸いなことに、代替手段 があります。論理的に単調な制御構造を入力してくださいif_/3

次のようif_/3に、具体化された list-membership 述語と一緒に使用できます。memberd_t/3

?- if_(memberd_t(X,[1,2]), X=2, X=4)。
X = 2; X = 4。
?- X=2, if_(memberd_t(X,[1,2]), X=2, X=4), X=2.
X = 2。
?- if_(memberd_t(X,[1,2]), X=2, X=4), X=2.
X = 2 ; 偽。
?- X=4, if_(memberd_t(X,[1,2]), X=2, X=4), X=4.
X = 4。
?- if_(memberd_t(X,[1,2]), X=2, X=4), X=4.
X = 4。

正しさスコア 5/5。効率スコア 4/5。

于 2015-10-16T15:08:20.913 に答える
15

これは、ルールでifステートメントを使用する場合に役立ちます。

max(X,Y,Z) :-
    (  X =< Y
    -> Z = Y
    ;  Z = X
    ).

http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.htmlに感謝します

于 2012-12-07T00:20:03.370 に答える
9

Prolog で if-then-else のようなものを表現するには、基本的に 3 つの異なる方法があります。それらを比較するには、 を検討してくださいchar_class/2。Foraおよびbクラスは、他のすべての用語に対してabandである必要があります。otherこれは次のようにぎこちなく書くことができます。

char_class(a, ab).
char_class(b, ab).
char_class(X, other) :-
   dif(X, a),
   dif(X, b).

?- char_class(Ch, Class).
   Ch = a, Class = ab
;  Ch = b, Class = ab
;  Class = other,
   dif(Ch, a), dif(Ch, b).

よりコンパクトに記述するには、if-then-else 構文が必要です。Prologには組み込みのものがあります:

?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
   Ch = a, Class = ab.

この答えは確かなものですが、不完全です。からの最初の回答( Ch = a ; Ch = b )のみが与えられます。他の答えは切り捨てられます。確かに、あまり関係がありません。

多くの場合「ソフト カット」と呼ばれるより良い構成 (名前を信じないでください。カットはカットはカットです) は、わずかに良い結果をもたらします (これは YAP にあります)。

?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

あるいは、SICStus にはif/3非常に似たセマンティクスがあります。

?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab.

したがって、最後の回答はまだ抑制されています。ここで、 SICStusYAP、およびSWIlibrary(reif)を入力します。それをインストールして、次のように言います。

?- use_module(library(reif)).

?- if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
   Ch = a, Class = ab
;  Ch = b, Class = ab
;  Class = other,
   dif(Ch, a), dif(Ch, b).

if_/3すべてが乱暴にネストされた if-then-else にコンパイルされることに注意してください。

char_class(Ch, Class) :-
   if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).

YAP 6.3.4 では次のように拡張されます。

char_class(A,B) :-
   ( A\=a
   ->
     ( A\=b
     ->
       B=other
     ;
       ( A==b
       ->
         B=ab
       )
     ;
       A=b,
       B=ab
     ;
       dif(A,b),
       B=other
     )
   ;
     ( A==a
     ->
       B=ab
     )
   ;
     A=a,
     B=ab
   ;
     dif(A,a),
     ( A\=b
     ->
       B=other
     ;
       ( A==b
       ->
         B=ab
       )
     ;
       A=b,
       B=ab
     ;
       dif(A,b),
       B=other
     )
   ).
于 2016-05-05T18:27:49.283 に答える
4

cuts最善の方法は、記号を持ついわゆる を使用すること!です。

if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.  
if_then_else(Condition, Action1, Action2) :- Action2.

以上が条件関数の基本構造です。

例として、max関数 を次に示します。

max(X,Y,X):-X>Y,!.  
max(X,Y,Y):-Y=<X.

カットに関するドキュメントをもっと読むことをお勧めしますが、一般的にカットはブレークポイントのようなものです。例: 最初のmax関数が真の値を返す場合、2 番目の関数は検証されません。

PS: 私は Prolog にかなり慣れていませんが、これは私が見つけたものです。

于 2013-10-11T07:52:19.733 に答える
3

Prolog program actually is big condition for "if" with "then" which prints "Goal is reached" and "else" which prints "No sloutions was found". A, Bmeans "A is true and B is true", most of prolog systems will not try to satisfy "B" if "A" is not reachable (i.e. X=3, write('X is 3'),nl will print 'X is 3' when X=3, and will do nothing if X=2).

于 2010-05-17T13:57:12.203 に答える
3
(  A == B ->
     writeln("ok")
;
     writeln("nok")
),

else の部分は必須です

于 2014-07-07T21:53:26.737 に答える