Domanda

Sono nuovo in Prolog e stavo solo pensando al motivo per cui questa regola mi dà un risultato falso dopo uno vero.

likes(1,banana).
likes(1,mango).

test :- likes(1,banana),likes(1,mango).

?- test.  
true;  
false.

Voglio sapere il motivo di questo falso.

È stato utile?

Soluzione

Il modo in cui funziona Prolog è valutare le query fino a quando non falliscono per negazione.

Qui hai stabilito due fatti:

likes(1, banana). che dice "A 1 piace la banana"

likes(1, mango). che dice "A 1 piace il mango"

Quindi hai stabilito una regola, che sostanzialmente valuta come:

left_hand_side :- right_hand_side. left_hand_side Se right_hand_side

Valutazione della regola mentre una query tenta di abbinare fatti e risultati true se può, e false se non può corrispondere.Una cosa importante da notare è che, se specificato, prolog continuerà a corrispondere ai fatti finché le regole lo valutano true.

Quindi facciamo un passo avanti test :- likes(1,banana),likes(1,mango).

Se test viene eseguito come query, prolog tenta prima likes(1,banana) il che è un fatto già accertato ed è vero.Quindi si passa a likes(1,mango) il che, ancora una volta, è un dato di fatto ed è vero.Prolog ha quindi raggiunto la fine della regola ed esce true.

A questo punto, se non stai cercando altre corrispondenze, puoi abbreviare la query e ottenere semplicemente true.Tuttavia, se stai cercando più (tutte) corrispondenze, prolog fare marcia indietro e prova a valutare nuovamente la regola, cercando più corrispondenze.

Tuttavia, poiché la tua regola corrisponde solo a "mi piace la banana e mi piace il mango" e abbiamo già abbinato likes(1,banana), quando prolog torna indietro e prova a valutare likes(1,banana) ancora una volta, poiché l'abbiamo già abbinato in precedenza, questa volta non c'è un altro fatto (in altre parole, non si può "mi piace" la banana più di una volta, a meno che non sia stato definito) da abbinare.Quindi è lì che false viene da.

Nel tuo interprete Prolog potresti essere in grado di tracciare l'esecuzione del tuo programma digitando trace. quindi eseguendo la tua query.La mia traccia è riportata di seguito:

| ?- trace
.
The debugger will first creep -- showing everything (trace)

(1 ms) yes
{trace}
| ?- test.
      1    1  Call: test ? 
      2    2  Call: likes(1,banana) ? 
      2    2  Exit: likes(1,banana) ? 
      3    2  Call: likes(1,mango) ? 
      3    2  Exit: likes(1,mango) ? 
      1    1  Exit: test ? 

true ? ;
      1    1  Redo: test ? 
      2    2  Redo: likes(1,banana) ? 
      2    2  Fail: likes(1,banana) ? 
      1    1  Fail: test ? 

(1 ms) no
{trace}
| ?-

Un'ultima cosa da notare:Se invece di premere ; al true ? prompt, se avessi premuto <ENTER>, la sceneggiatura sarebbe terminata solo con il file true.

Sono felice che tu abbia posto questa domanda perché mi ha permesso un piccolo ripasso su Prolog, che mi piace molto ma che non uso da molto tempo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top