Czy Prolog naprawdę opiera się na założeniu zamkniętego świata?
Zgodnie z założeniem zamkniętego świata ,
to, co obecnie nie jest znane, jest fałszywe
Często mówi się, że semantyka Prologu jest zgodna z założeniem zamkniętego świata, na przykład tutaj :
Prolog opiera się na założeniu zamkniętego świata (CWA) - to znaczy, jeśli zdanie nie znajduje się w bazie danych i nie można go wyprowadzić z bazy danych, to jest nieprawdą.
Jednak nie do końca zachowuje się w ten sposób. Spodziewałbym się, że pod CWA
?- a.
false.
Ale zamiast tego w SWI-Prologu otrzymuję:
?- a.
ERROR: Undefined procedure: a/0 (DWIM could not correct goal)
Dlaczego? Czy błędem jest twierdzenie, że Prolog jest oparty na CWA?
Odpowiedzi
Mówiąc o założeniu Closed-World Assumption (CWA) w kontekście Prologu, należy rozróżnić między nieznanymi predykatami a znanymi predykatami w systemie (runtime). W obu przypadkach predykaty z klauzulami lub bez.
Wywołanie nieznanego predykatu domyślnie spowoduje zgłoszenie błędu istnienia predykatu. Istnieje standardowa flaga, unknown
której domyślną wartością jest error
, którą można ustawić fail
. To da ci zachowanie, którego najwyraźniej szukasz. Sill, zdecydowanie radzę pozostawić flagę ustawioną na domyślną wartość error
, ponieważ pozwala to na łatwiejsze wykrycie predykatów programowania (np. Literówki w nazwach predykatów lub Arity).
Co sprawia, że predykat jest znany środowisku wykonawczemu? Dyrektywy predykatów lub klauzule predykatów. Najbardziej znanym przykładem jest dynamic/1
dyrektywa. Jeśli Twój kod składa się wyłącznie z następującego tekstu:
:- dynamic(foo/1).
Następnie po skompilowaniu i załadowaniu możesz spodziewać się:
?- foo(_).
no.
Ale inne dyrektywy mają ten sam efekt (np. multifile/1
I discontiguous/1
zakładając, że jest to standard zgodny z implementacją Prologu!).
Zatem dla znanych predykatów interpretacja CWA w Prologu jest prosta: to, czego nie możemy udowodnić, jest fałszywe. To znaczy negacja przez niepowodzenie , co nie jest tym samym, co negacja logiczna . Nazwa Prolog pochodzi od programowania w logice, ale Prolog ma być również pragmatycznym i praktycznym językiem programowania.
To, czego brakuje w Prologu (a zapewnia to np. Logtalk ), to możliwość zadeklarowania predykatu bez konieczności deklarowania go jako dynamicznego lub wieloplikowego, lub ... lub wymagającego podania dla niego klauzul (patrz np. Ten przykład ). Zapewnia to prostszą i jaśniejszą semantykę CWA: wywołanie zadeklarowanego predykatu bez klauzul kończy się niepowodzeniem (bez potrzeby zmiany unknown
flagi powodującej problem ); wywołanie niezadeklarowanego predykatu powoduje błąd istnienia predykatu.
Mam nadzieję że to pomoże. Poszukiwanie negacji jako porażki powinno dostarczyć dalszych wyjaśnień.
Twoje zapytanie musi być w samym języku, a
aby zdanie a/0
było w języku, tj. Zdefiniowane jako predykat. Wszystkie nullary predykaty w języku są zdaniami. Nie możesz zapytać o nowy termin jako predykat bez uprzedniego dodania go do języka.
Do a/1
kiedy można zdefiniować ją tak jak a(b).
jest to w języku, a następnie kwerenda a(X), dif(X,b)
nie powiedzie się, ponieważ system prolog nie zna żadnych innych warunków, które spełniają to i zakładając ścisłą świecie istnieje żadna inna.