2012-04-12 20 views

Respuesta

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

Para el registro, esto se llama una condicional.

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

Tenga en cuenta que si-entonces-sino sólo es necesario si no puede expresar las diferentes condiciones de coincidencia de patrones en diferentes cláusulas. Todo lo que se puede expresar mediante la coincidencia de patrones debe expresarse mediante la coincidencia de patrones, ya que esto generalmente conduce a un código más general y también más eficiente.

1

No es realmente fácil de encontrar, en parte porque (como señala @mat) en Prolog existe una alternativa idiomática. Puede encontrar here documentación de SWI-Prolog, aunque de manera muy sucinta, es precisa. Cito un punto relevante:

Tenga en cuenta que (If -> Then) actúa como (If -> Then; fail), haciendo que la construcción falle si la condición falla. Esta semántica inusual es parte de la ISO y de todos los estándares de Prolog de facto.

2

El ->/2 solo es necesario si quiere imponer cierto determinismo. Actúa como un corte local. Pero en caso de que quiera que su código mantenga el algo no determinista, no es necesario usar ->/2.

Tome el siguiente código 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; 
    } 

}

Esto puede ser codificado en Prolog sin ->/2 de la siguiente manera:

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

La ventaja es ahora que se puede se utilizará para verificar listas de booleanos y para generar listas de booleanos:

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

En general, la disyunción (;)/2 se puede distribuir en múltiples cláusulas . Si esto se combina con la unificación en movimiento (=)/2 en , se puede ganar algo de velocidad, ya que el predicado es entonces que generalmente es más fácil de indexar.

Así es como una formulación alternativa de list_of_bool vería como mediante la eliminación (;)/2 y (=)/2:

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

lo anterior funciona exactamente de la misma (en realidad funciona mejor, ya que en la primera consulta se deja ningún punto de elección, lo que la (;)/2 por lo general no detectará sin (->)/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.. 

Así es también como se puede iniciar Prolog. Con reglas solo y sin disyunción (;)/2 y sin unificación (=)/2.El más tarde dos ya están allí en las cláusulas Horn subyacentes.

Suponga que tiene un prólogo y sin (;)/2 y no (=)/2, y que no es necesario un corte transparente (;)/2, entonces se podría definir estas construcciones por sí mismo de la siguiente manera :

X = X. 

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

adiós

Cuerno Cláusula
http://en.wikipedia.org/wiki/Horn_clause

Cuestiones relacionadas