2011-01-26 15 views

cevap

8

Prolog'un if-then-else yapı içinde "gizli" kesik var: düzgün yüklemi yazarsan kesim gereksizdir yüzden, geri izleme, başarılı olamaz Bu bir tuhaflıktan başka bir şey değil, ama Prolog, eğer o zaman ya da öyleyse-başka bir yapının “öncülünü” oluşturan altgale dayanmıyor. Burada, eğer X < 0 ilk denemeyi başarırsa, o zaman "else" maddesinin "else" maddesinin seçimi tercih edilir (dolayısıyla bu davranışın "gizli" bir kesim olarak açıklaması).

yüklemi söz konusu yazılı olarak abs2/2 ait ilk fıkrada bir kesim için bir rolün daha vardır. Nicholas'ın belirttiği gibi, ikinci fıkranın sonundaki kesintinin herhangi bir etkisi yoktur (oraya vardığınızda hiçbir seçim puanı kalmaz). Ama Kaarel'in belirttiği gibi, eğer birinci fıkra başarılı olursa, açık bir seçim noktası vardır.

abs2(X,X) :- X >= 0, !. 
abs2(X,Y) :- Y is -X. 
Nicholas yorumları da yollar önermek

için "arithmetize" mutlak değeri (bir mantık tanımını kullanmak yerine) ve kaçının: yazdım olurdu Peki

, bir kesik kullanımına izin veren, bu Bu şekilde "kes".

+1

" Gizli kesim "adlı bir ad, bir kesim gibi davranmaz:!/0, ayrıca, alternatif cümlelerin denenmesini de engeller, ancak yerel if-then-else-başka bir şey yapmaz. Bu yüzden bu zayıf terminolojiyi buluyorum. – mat

+2

@mat: Daha iyi bir terminoloji öğrenmekten mutluluk duyarız. Çözümün (görünür) kesimden kaçınılmasını sağlayan bir çözüm sunarken "gizli kesim" yazdım, böylece okuyucu benim çözümümün geçerli olup olmadığını veya "aldatmaca" olup olmadığını yargılayabilir. "If-then-else" içinde yerelleştirilmiş taahhüt/kesintinin bir açıklaması için Kontrol Tahminleri (Sec. 2.4.7) için SWI-Prolog belgelerini karşılaştırın. http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%274.7%27,swi%28%27/doc/Manual/control.html%27%29%29 – hardmath

5

Prolog'um biraz paslı, ama neden kesime ihtiyacınız var?

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X. 

:

abs(X, Y) :- number(X) , X < 0 , Y is -X . 
abs(X, X) :- number(X) , X >= 0 . 
+4

Kodunuzun hala seçim noktasını bırakır. Bu seçim başarısızlığa yol açar, ancak yine de dikkate alınır. Bir kesim bundan kaçınacaktır. – Kaarel

+3

İntegral değerlerle uğraştığınızı biliyorsanız, ABS'yi bir seçim noktası ile bitleri ikiye ayırarak hesaplayabilirsiniz: http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerAbs –

+6

Başka bir seçenek de budur. : 'abs (X, Y): - Y işareti (X) * X'dir. (Prolog uygulamanızın yerleşik bir işareti/1 yüklemesini desteklediğini varsayar). –

3

'u kullanmanıza gerek yok!

Basitçe yazın:

abs2(X,Y) :- Y is abs(X). 
İlgili konular