"إذا" في مقدمة؟
-
27-09-2019 - |
سؤال
هل هناك طريقة للقيام إذا كان في مقدمة ، على سبيل المثال إذا كان المتغير 0 ، ثم للقيام ببعض الإجراءات (اكتب نصًا إلى المحطة). ليست هناك حاجة إلى أخرى ، لكن لا يمكنني العثور على أي وثائق إذا.
المحلول
مسند مقدمة قياسي سوف تفعل هذا.
isfive(5).
سيتم تقييمها إلى True إذا اتصلت بها بـ 5 وفشلت (إرجاع خطأ) إذا قمت بتشغيله مع أي شيء آخر. لعدم تساويك تستخدم =
isNotEqual(A,B):- A\=B.
من الناحية الفنية ، لا يتوحد ، لكنه يشبه المساواة.
تعلم 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.')
)
لاحظ أنه إذا حذفت البلية الأخرى ، فإن فشل الحالة يعني أن كل ما إذا سيفشل الـ statement. لذلك ، أوصي دائمًا بما في ذلك البنى الأخرى (حتى لو كان الأمر كذلك true
).
تقدم Prolog "Unify" -
لذلك ، في Langauge الضروري سأكتب
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
أولاً ، دعنا نتذكر بعض منطق الدرجة الأولى الكلاسيكية:
"لو ص من ثم س آخر R "يعادل" (P و س) أو (non_p و ص) ".
كيف يمكننا التعبير عن "If-then-else" مثل الذي - التي في Prolog؟
دعنا نأخذ المثال الملموس التالي:
لو
X
هو عضو في القائمة[1,2]
من ثمX
يساوي2
آخرX
يساوي4
.
يمكننا مطابقة النمط أعلاه (""لو ص من ثم س آخر ص ") إذا ...
- شرط
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).
دعنا نتحقق من طرق مختلفة للتعبير عن "If-then-else" في Prolog!
(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
تُرجع الوظيفة قيمة حقيقية ، لا يتم التحقق من الوظيفة الثانية.
ملاحظة: أنا جديد إلى حد ما على Prolog ، ولكن هذا ما اكتشفته.
هناك أساسًا ثلاث طرق مختلفة كيفية التعبير عن شيء مثل If-then-else في Prolog. لمقارنتهم النظر 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).
لكتابة الأشياء بشكل أكثر إحكاما ، هناك حاجة إلى بنية إذا كانت 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" مع "ثم" الذي يطبع "الهدف الذي تم الوصول إليه" و "آخر" الذي يطبع "لم يتم العثور على مقلوب". A, B
يعني "A صحيح و B صحيح" ، معظم أنظمة Prolog لن تحاول إرضاء "B" إذا لم يكن "A" يمكن الوصول إليه (أي X=3, write('X is 3'),nl
سوف طباعة "x هي 3" عندما x = 3 ، ولن تفعل شيئًا إذا كان x = 2).
( A == B ->
writeln("ok")
;
writeln("nok")
),
الجزء الآخر مطلوب
يجب أن تقرأ تعلم مقدمة الآن! الفصل 10.2 باستخدام قطع. هذا يوفر مثالاً:
max(X,Y,Z) :- X =< Y,!, Y = Z.
ليقال ،
Z
يساوي Y
لو !
صحيح (وهو دائمًا) و X
هو <= Y
.