2012-04-12 3 views

Odpowiedz

5
(cond1 -> 
    consequent1 
; cond2 -> 
    consequent2 
; 
    alternative 
) 

Dla przypomnienia, to nazywa się warunkową.

8
( If1 -> Then1 
; If2 -> Then2 
; ... 
; otherwise 
). 

Zauważ, że if-then-else jest konieczne tylko, jeśli nie mogą wyrażać różne warunki dopasowując wzór w różnych punktach. Wszystko, co można wyrazić za pomocą dopasowania do wzorca, powinno być wyrażone poprzez dopasowanie do wzorca, ponieważ zazwyczaj prowadzi to do bardziej ogólnego i bardziej wydajnego kodu.

1

Nie jest to łatwe do znalezienia, częściowo dlatego, że (jak zauważył @mat) w Prologu istnieje alternatywa idiomatyczna. Możesz znaleźć dokumentację SWI-Prolog here, ale zbyt daleko, to jest dokładne. Cytuję odpowiedni punkt:

Należy zauważyć, że (jeśli -> wtedy) działa jako (Jeżeli -> to; fail), wykonanie konstrukcji nie powiedzie się, jeśli warunek się nie powiedzie. Ta niezwykła semantyka jest częścią ISO i wszystkich de facto standardów Prologu.

2

->/2 jest potrzebny tylko, jeśli chcesz narzucić pewien determinizm. Działa jak lokalny krój. Ale jeśli chcesz, aby twój kod nadal zawierał jakiś niedeterminizm, nie musisz używać ->/2.

Weźmy następujący kod KONIECZNIE:

boolean listOfBool(Object obj) { 
    if (obj instanceof ConsCell) { 
     if (((ConsCell)ob).head() instanceof Boolean) { 
      return listOfBool(((ConsCell)ob).tail()); 
     } else { 
      return false; 
     } 
    } else if (obj == null) { 
     return true; 
    } else { 
     return false; 
    } 

}

To może być zakodowany w Prologu bez ->/2 w następujący sposób:

% bool(+Bool) 
% bool(-Bool) 
bool(0). 
bool(1). 

% list_of_bool(+List) 
% list_of_bool(-List) 
list_of_bool(L) :- 
    (L = [X|Y], bool(X), list_of_bool(Y); 
    L = []). 

Zaletą jest to, że można służy do sprawdzania list o nazwach od i do generowania list booleans:

?- list_of_bool([0,1,0]). 
Yes 
?- list_of_bool([0,1,2]). 
No 
?- List=[_,_,_], list_of_bool(List). 
List = [0, 0, 0] ; 
List = [0, 0, 1] ; 
List = [0, 1, 0] ; 
List = [0, 1, 1] Etc.. 

Zasadniczo alternatywa (;)/2 może być rozpowszechniana w wielu klauzulach . Jeśli jest to połączone z przeniesieniem unifikacji (=)/2 do głowicy, to można uzyskać pewną prędkość, ponieważ predykat jest wówczas zwykle lepiej podatny na indeksowanie.

Oto jak alternatywne sformułowanie list_of_bool wyglądałby jak eliminując (;)/2 a (=)/2:

% list_of_bool2(+List) 
% list_of_bool2(-List) 
list_of_bool2([X|Y]) :- bool(X), list_of_bool2(Y). 
list_of_bool2([]). 

Powyższe działa dokładnie tak samo (to faktycznie działa lepiej, ponieważ w pierwszym zapytaniu sensu wybór jest w lewo, co (;)/2 zazwyczaj nie wykrywa bez (->)/2):

?- list_of_bool2([0,1,0]). 
Yes 
?- list_of_bool2([0,1,2]). 
No 
?- List=[_,_,_], list_of_bool(List). 
List = [0, 0, 0] ; 
List = [0, 0, 1] ; 
List = [0, 1, 0] ; 
List = [0, 1, 1] Etc.. 

jest to również, jak Prolog może zostać uruchomiony. Tylko z regułami: i bez rozłączności (;)/2 i bez unifikacji (=)/2. później dwa są już w podstawowych klauzulach Horn.

Załóżmy, że masz Prolog bez (;)/2 i NO (=)/2 i nie trzeba cięcie przezroczysty (;)/2, a następnie można określić tych konstrukcji przez siebie następująco :

X = X. 

(A ; _) :- A. 
(_ ; B) :- B. 

Bye

Horn Klauzula
http://en.wikipedia.org/wiki/Horn_clause