2012-04-12 9 views

risposta

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

Per la cronaca, questo si chiama un condizionale.

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

Si noti che if-then-else è necessario solo se non è possibile esprimere le diverse condizioni mediante la corrispondenza del modello in clausole diverse. Tutto ciò che può essere espresso dalla corrispondenza del modello dovrebbe essere espresso dalla corrispondenza del modello, in quanto questo in genere porta a un codice più generale e anche più efficiente.

1

Non è davvero facile da trovare, in parte perché (come notato da @mat) in Prolog c'è un'alternativa idiomatica. È possibile trovare la documentazione SWI-Prolog here, anche se in modo molto succinto, è accurata. Cito un punto pertinente:

Si noti che (Se -> Quindi) agisce come (Se -> Allora, esito negativo), facendo fallire il costrutto se la condizione non riesce. Questa semantica insolita fa parte degli standard ISO e di tutti gli standard Prolog.

2

Il ->/2 è necessario solo se si vuole imporre un determinato determinismo. Si comporta come un taglio locale. Ma nel caso in cui si desideri che il proprio codice mantenga il non determinismo , non è necessario utilizzare ->/2.

Prendere il seguente codice imperativo:

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; 
    } 

}

Questo può essere codificato in Prolog, senza ->/2 come segue:

% 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 = []). 

Il vantaggio è ora che si può essere utilizzato per controllare gli elenchi di booleani e per generare elenchi di booleani:

?- 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.. 

In genere la disgiunzione (;)/2 può essere distribuita su più clausole . Se questo è combinato con lo spostamento dell'unificazione (=)/2 in la testa, allora si può guadagnare un po 'di velocità, dal momento che il predicato è quindi generalmente più adatto all'indicizzazione.

Ecco come una formulazione alternativa list_of_bool apparirebbe simile riducendo (;)/2 e (=)/2:

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

I lavori sopra esattamente lo stesso (effettivamente funziona meglio, dal momento che nella prima query nessun punto scelta è lasciata, ciò che il (;)/2 di solito non rileverà senza (->)/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.. 

Questo è anche il modo in Prolog può essere avviato. Con le regole solo e nessuna disgiunzione (;)/2 e nessuna unificazione (=)/2.I due successivi sono già presenti nelle clausole Horn sottostanti.

Supponiamo di avere un Prolog senza (;)/2 e no (=)/2, e non hai bisogno di un taglio trasparente (;)/2, allora si potrebbe definire questi costrutti da soli come segue :

X = X. 

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

Bye

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