プロログの「場合」?
-
27-09-2019 - |
質問
PrologでIFを実行する方法はありますか?たとえば、変数が0の場合、いくつかのアクションを実行します(端末にテキストを書きます)。他の人は必要ありませんが、ifのドキュメントが見つかりません。
解決
標準的なProlog Predicateがこれを行います。
isfive(5).
5で呼び出す場合はtrueに評価し、他の何かで実行する場合はfail(falseを返します)。等しくないために =を使用します
isNotEqual(A,B):- A\=B.
技術的には統合されませんが、等しくないと似ています。
Prologを学ぶことは、Prologを学ぶための良いウェブサイトです。
編集:別の例を追加します。
isEqual(A,A).
他のヒント
はい、ISO Prologにはそのような制御構造があり、 ->
. 。あなたはそれをこのように使用します:
( condition -> then_clause ; else_clause )
以下は、クロースの場合のチェーンを使用する例です。
( X < 0 ->
writeln('X is negative. That's weird! Failing now.'),
fail
; X =:= 0 ->
writeln('X is zero.')
; writeln('X is positive.')
)
他の条件を省略した場合、失敗する状態は、IFステートメント全体が失敗することを意味することに注意してください。したがって、私は常に他の条項を含めることをお勧めします(たとえそれがただであっても true
).
Prolog Prendicates 'Unify' -
だから、私が書く命令的な言語で
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
プロログで私は書くでしょう
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
両方のスタイルを理解すると、実際にははるかに明確です。
「私はFooが5の特別なケースのためにバズーです」
「私はfooが5でない場合の通常のケースのためにバズーです」
これを使用するのに役立ちました もしも ルールの声明。
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
ありがとう http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html
まず、いくつかの古典的な一次ロジックを思い出しましょう。
"もしも p それから Q そうしないと r "は"に相当します(p と Q) また (non_p と r)」。
「if-then-else」のような表現方法 それ プロログで?
次の具体的な例を考えてみましょう。
もしも
X
リストのメンバーです[1,2]
それからX
平等です2
そうしないとX
平等です4
.
上記のパターンに合わせることができます(」もしも p それから Q そうしないと r ")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). 偽. % 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. 偽. % 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. 偽. % WRONG
正しさのスコア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. 偽. % WRONG
正しさのスコア3/5。効率スコア1/5。
(予備)概要:
(P,Q ; non_P,R)
正しいですが、の個別の実装が必要ですnon_P
.(P -> Q ; R)
インスタンスが不十分な場合、宣言的なセマンティクスを失います。(P *-> Q ; R)
「それほど」不完全です(P -> Q ; R)
, 、しかし、同様の問題があります。
幸運なことに、そこに それは 代替品:論理的に単調な制御コンストラクトを入力します 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で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.
したがって、最後の答えはまだ抑制されています。入力します library(reif)
にとって sicstus, ええ, 、 と 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
)
).
Prologプログラムは、実際には「IF」を「IF」と「印刷」と「到達」と「else」を印刷する「スルートは見つかりませんでした」の大きな条件です。 A, B
「aは真であり、bは真」」を意味します。プロログシステムのほとんどは、「a」が到達できない場合、「b」を満たそうとはしません(つまり、 X=3, write('X is 3'),nl
x = 3の場合、 'xは3'が3 'で、x = 2)の場合は何もしません。
( A == B ->
writeln("ok")
;
writeln("nok")
),
他の部分が必要です
あなたは読むべきです 今すぐプロログを学びましょう!第10.2章カットを使用します. 。これは例を示しています:
max(X,Y,Z) :- X =< Y,!, Y = Z.
言われるべき、
Z
に等しい Y
もしも !
本当です(それは常にそうです) と X
は <= Y
.