プロローグでifを実行する方法はありますか?変数が0の場合、何らかのアクションを実行します(端末にテキストを書き込みます)。 elseは必要ありませんが、ifのドキュメントは見つかりません。
標準のプロローグ述語がこれを行います。
isfive(5).
5で呼び出すとtrueに評価され、それ以外で実行すると失敗します(falseを返します)。等しくない場合は、\ =を使用します
isNotEqual(A,B):- A\=B.
技術的には統一されていませんが、等しくないことに似ています。
Learn Prolog Nowは、プロローグを学習するのに適したWebサイトです。
編集:別の例を追加します。
isEqual(A,A).
はい、ISO Prologには->
と呼ばれる制御構造があります。次のように使用します。
( 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
であっても)。
プロローグ述語 'unify'-
だから、命令的な言語で私は書きます
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
プロローグに書きます
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
両方のスタイルを理解すると、実際にははるかに明確になります。
"fooが5である特別な場合のバズーです"
"fooが5でない通常の場合はバズーです"
これは、ルールでifステートメントを使用するのに役立ちます。
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html に感謝
最初に、古典的な一次論理を思い出してみましょう。
「IfPthenQelseR」は「(P andQ)or(non_PandR)」。
次の具体例を見てみましょう。
If
X
はリスト[1,2]
のメンバーであるthenX
は2
に等しいelseX
は4
と等しい。
上記のパターンに一致させることができます( "IfPthenQelseR" )if ...
P
はlist_member([1,2],X)
であり、non_P
はnon_member([1,2],X)
です、Q
はX=2
であり、R
はX=4
です。リスト(非)メンバーシップを純粋な方法で表現するには、以下を定義します。
list_memberd([E | Es]、X): E = X ; dif(E、X)、 list_memberd(Es、X) )。 non_member(Es、X):- maplist(dif(X)、Es)。
Prologで「if-then-else」を表現するさまざまな方法を見てみましょう。
(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。
(P -> Q ; R)
?-(list_memberd([1,2]、X)-> X = 2; X = 4)。 false。 %WRONG ?-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。 false。 %WRONG ?-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。 false。 % 違う
正しさスコア2/5。効率スコア2/5。
(P *-> Q ; R)
?-(list_memberd([1,2]、X)*-> X = 2; X = 4)。 X = 2 ;偽。 %WRONG ?-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。 false。 % 違う
正しさスコア3/5。効率スコア1/5。
(予備)要約:
(P,Q ; non_P,R)
は正しいですが、non_P
の個別の実装が必要です。
インスタンス化が不十分な場合、(P -> Q ; R)
は宣言セマンティクスを失います。
(P *-> Q ; R)
は(P -> Q ; R)
よりも「不完全」ですが、同様の問題があります。
幸いなことに、are選択肢があります:論理的に単調な制御構造を入力してくださいif_/3
!
---(if_/3
を、具体化されたリストメンバーシップ述語 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。
最善の方法は、!
というシンボルを持つ、いわゆる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にかなり慣れていないが、これは私が見つけたものだ。
Prologでif-then-elseのようなものを表現するには、基本的に3つの異なる方法があります。それらを比較するには、char_class/2
を検討してください。 a
およびb
の場合、他のすべての用語では、クラスはab
および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.
したがって、最後の答えはまだ抑制されています。次に、 SICStus 、 [〜#〜] yap [〜#〜] 、および にlibrary(reif)
と入力します[〜#〜] swi [〜#〜] 。それをインストールして言う:
?- 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
)
).
プロローグプログラムは、実際には「if」と「then」、「ゴールに到達しました」、「else」と「No sloutions was found」を出力するための大きな条件です。 _A, B
_ means「Aが真でBが真」。プロローグシステムのほとんどは、「A」に到達できない場合(「X=3, write('X is 3'),nl
」は「Xは3」を出力します) X = 3の場合、X = 2の場合は何もしません。
( A == B ->
writeln("ok")
;
writeln("nok")
),
Elseの部分は必須です
Prolog Nowを学びましょう!第10.2カットの使用 をお読みください。これは例を提供します:
max(X,Y,Z) :- X =< Y,!, Y = Z.
言われるように、
Z
はY
と等しい[〜#〜] if [〜#〜]!
が真(常に)[〜#〜] and [〜#〜]X
は<= Y
。