Prolog i wykrzyknik.

0

Witam, mam pytanie. Z tego co wyczytałem to wykrzyknik powoduje, że jeżeli klauzula w której jest umieszczony się wykona, to nie będą już sprawdzane pozostałe. Czy może ktoś wyjaśnić mi dlaczego w tych dwóch przypadkach, wynik jest taki sam przy wywołaniu na przykład " ?- test(x,y)." i wynosi "test1 true." Wychodzi na to, że wykrzyknik jest zbędny, bo jeżeli klauzula okazuje się prawdą, to następna już i tak nie jest sprawdzana. Wtedy by wyświetliło również napis "test2". Z góry dzięki.

test(x,y) :- write("test1"),!.
test(x,y) :- write("test2").

test(x,y) :- write("test1").
test(x,y) :- write("test2").
0

Z tego co wyczytałem to wykrzyknik powoduje, że jeżeli klauzula w której jest umieszczony się wykona, to nie będą już sprawdzane pozostałe.

To uproszczenie, do tego poziomu uproszczone że prawie błędne.
Prolog robi sobie "drzewo" backtrackowania, i ! to tzw. odcięcie - powoduje ono że prolog uznaje że "na pewno nie warto się już wracać, ścieżka na której jesteśmy jest dobra".

Czy może ktoś wyjaśnić mi dlaczego w tych dwóch przypadkach, wynik jest taki sam przy wywołaniu na przykład " ?- test(x,y)." i wynosi "test1 true." Wychodzi na to, że wykrzyknik jest zbędny, bo jeżeli klauzula okazuje się prawdą, to następna już i tak nie jest sprawdzana. Wtedy by wyświetliło również napis "test2". Z góry dzięki.

Ale wcale nie jest zbędny.

Po prostu prolog nie jest stworzony do pisania w nim imperatywnie, i "write" to bardzo doszywana na siłę rzecz. Ogólnie nie polecam tak pisać w prologu, kompletnie niszczy sens używania go.

Faktycznie w obu przypadkach wynik jest taki sam: "true". Ale to co jest wypisywane na ekran się różni: w pierwszym przypadku wypisane będzie tylko "test1", a w drugim w ogólnym przypadku "test1" "test2".
Ale test2 się nie wypisze jeśli prolog nie spróbuje go zmatchować. Skoro pierwsze dopasowanie jest prawdą, to po co prolog ma próbować więcej? Możesz go za to zmusić do backtrackowania, np. pisząc

test(x, y), fail.

Albo klikając w swoim IDE jakiś odpowiednik "next", "more", etc.

Wtedy kiedy pierwsze dopasowanie się nie uda, prolog zbacktrackuje do test() i spróbuje zmatchować test2.

0

A możesz podać jakiś prostu przykład, w którym rzeczywiście wynik będzie inny dzięki "!", niż gdybyśmy go nie użyli?

0

No ale już Twój kod daje różny wynik (na ekran), po prostu źle go uruchamiasz.

Jeśli musi być w jednym dopasowaniu, to też podałem (to z fail), albo ew. można użyć findall.

1 użytkowników online, w tym zalogowanych: 0, gości: 1