2011-01-26 8 views

Odpowiedz

8

Tam jest „ukryty” cięcie w if-then-else konstrukcie Prologu:

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

Jest to coś dziwnego, ale Prolog nie wycofuje się na subgoale, które stanowi "przesłankę" konstruktu if-then lub if-then-else. Tutaj, jeśli X < 0 powiedzie się po pierwszej próbie, wówczas zostaje zatwierdzony wybór klauzuli "wtedy" w stosunku do "innej" (stąd opis tego zachowania jako "ukrytego" cięcia).

Jest większą rolę na cięcie w pierwszej klauzuli orzecznika abs2/2 jak napisane w pytaniu. Jak zauważa Nicholas, cięcie na końcu drugiego zdania nie ma żadnego efektu (nie ma punktów wyboru, kiedy się tam dostaniesz). Ale, jak zaznacza Kaarel, punkt wyboru pozostaje otwarty, jeśli pierwsza klauzula się powiedzie.

Więc co bym napisał, umożliwiając stosowanie cięcia, to:

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

komentarze Mikołaja sugerują również sposoby „arithmetize” wartość bezwzględna (zamiast stosować definicję logiki) i unikać "wyciąć" w ten sposób.

+1

To, co nazwałeś" ukrytym krojem ", nie zachowuje się jak wycięcie:!/0 również uniemożliwia wypróbowanie alternatywnych klauzul, ale lokalne Zatwierdź w if-then-else, nie. Dlatego też znajduję tę słabą terminologię. – mat

+2

@mat: Byłbym szczęśliwy, gdyby nauczyłem się lepszej terminologii. Napisałem "ukryte cięcie" jako rodzaj ujawnienia oferując moje rozwiązanie, unikając (oczywistego) użycia cięcia, aby czytelnik mógł ocenić, czy moje rozwiązanie jest prawidłowe, czy też "oszukać". Porównaj dokumentację SWI-Prolog dla Predykatów kontroli (rozdział 2.4.7), aby uzyskać wyjaśnienie zlokalizowanego zatwierdzenia/cięcia w "if-then-else". 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

Mój prolog jest nieco zardzewiały, ale dlaczego potrzebujesz cięcia? Jeśli piszesz predykat odpowiednio, wycofywania nie może się udać, więc cięcie jest konieczne:

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

Kod nadal pozostawia punkt wyjścia. Ten wybór prowadzi do niepowodzenia, ale mimo to jest brany pod uwagę. Cięcie pozwoliłoby na uniknięcie tego. – Kaarel

+3

Jeśli wiesz, że masz do czynienia z wartościami całkowitymi, możesz obliczyć ABS z punktem wyboru za pomocą twiddling bitów: http://www.graphics.stanford.edu/~seander/bithacks.html#IntegerAbs –

+6

Inna opcja to : 'abs (X, Y): - Y jest znakiem (X) * X .' (zakładając, że implementacja prologu obsługuje wbudowany znak/1 predykat). –