2011-09-06 11 views
5

sto leggendo http://cs.union.edu/~striegnk/learn-prolog-now/html/node3.html#subsec.l1.kb1, ma sto avendo difficoltà di eseguire il seguente predicato:Definire predicati in SICStus Prolog/SWI-Prolog REPL

SICStus 4.0.1 (x86-win32-nt-4): Tue May 15 21:17:49 WEST 2007 
| ?- woman(mia). 
! Existence error in user:woman/1 
! procedure user:woman/1 does not exist 
! goal: user:woman(mia) 
| ?- 

Se, d'altra parte, mi scrivono in un file e eseguire consultare il file, sembra funzionare bene ...

Sono autorizzato a definire i predicati solo in un file dopo averli consultati? Non posso farlo solo nell'editor stesso?

risposta

7

È necessario immettere woman(mia). in un file per asserirlo come un fatto. Se lo scrivi nell'interprete, è preso come una query, non un fatto.

Dal SWI Prolog FAQ:

Termini immessi al livello superiore sono processi come query, mentre termini che compaiono in un file che viene caricato in Prolog viene elaborato come un insieme di regole e di fatti. Se un testo si legge come sotto, questa è una regola.

carnivore(X) :- animal(X), eats_meat(X). 

Cercando di inserire questo al livello superiore si verifica l'errore di seguito. Perché? Perché una regola è un termine :-(Testa, Corpo), e perché il primo livello interpreta i termini come query. Non esiste un predicato con il nome: - e due argomenti.

?- carnivore(X) :- animal(X), eats_meat(X). ERROR: Undefined 
procedure: (:-)/2 ERROR: Rules must be loaded from a file ERROR: 
See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt 

Non è stupido questo? Beh no. Supponiamo di avere un termine eats_meat (rataplan). Se questo appare in un file, si afferma il fatto che rataplan mangia carne. Se appare al livello superiore, chiede a Prolog di provare a provare se rataplan mangia carne.

Se un testo recita

:- use_module(library(clpfd)). 

Questa è una direttiva. Le direttive sono simili alle query, ma invece di che chiede al toplevel di fare qualcosa, chiedono al compilatore di fare qualcosa . Come regole e fatti, tali termini appartengono ai file.

Invece di scrivere su un file, è possibile utilizzare anche lo assert in toplevel (come spiegato più avanti nelle Domande frequenti).

+1

Quindi, in questo caso * asserire (donna (mia)) *. farei proprio quello che voglio? –

+0

@devoured: Sì. – sepp2k

+1

Il messaggio di errore può essere fuorviante per un principiante. Poiché le regole possono anche essere caricate dall'utente, che non è esattamente un file. Ma questo è un problema generale nella creazione di buoni messaggi di errore. –

10

È un po 'noioso fare predicati nel repl. Si potrebbe fare

| ?- ['user']. 
woman(mia). 
^D 

cioè consultare l'input dell'utente, o

| ?- assertz(woman(mia)). 

affermarla. Sia IMO imbarazzante - potrebbe esserci un modo migliore, però, proprio non lo so. In generale è più facile usare uno script.