2010-07-19 14 views
10

Ho la seguente semplice parser espressione:numeri analisi con più cifre in Prolog

expr(+(T,E))-->term(T),"+",expr(E). 
expr(T)-->term(T). 

term(*(F,T))-->factor(F),"*",term(T). 
term(F)-->factor(F). 

factor(N)-->nat(N). 
factor(E)-->"(",expr(E),")". 

nat(0)-->"0". 
nat(1)-->"1". 
nat(2)-->"2". 
nat(3)-->"3". 
nat(4)-->"4". 
nat(5)-->"5". 
nat(6)-->"6". 
nat(7)-->"7". 
nat(8)-->"8". 
nat(9)-->"9". 

Tuttavia questa supporta solo i numeri 1 cifra. Come posso analizzare i numeri con più cifre in questo caso?

+0

Quale prologo stai usando? I miei non hanno il "->" pensa iirc. (SWI-Prolog) – InsertNickHere

+0

Sto usando anche SWI-Prolog ^^ – ubuntudroid

+0

Huh. Dovrebbe essere: - invece? * scratchhead * – InsertNickHere

risposta

9

Utilizzare le variabili di accumulo e passare quelle in chiamate ricorsive. Di seguito, A e A1 sono l'accumulatore.

digit(0) --> "0". 
digit(1) --> "1". 
% ... 
digit(9) --> "9". 

nat(N) --> digit(D), nat(D,N). 
nat(N,N) --> []. 
nat(A,N) --> digit(D), { A1 is A*10 + D }, nat(A1,N). 

Si noti che il primo nat clausola inizializza l'accumulatore consumando una cifra, perché non si desidera far corrispondere la stringa vuota.

+0

@ubuntodroid: Penso che questa sia una buona soluzione se devi implementare il numero analizzando te stesso. Non so se esiste un predicato per analizzare i numeri naturali per impostazione predefinita in Prolog. Il codice può anche essere ridotto se si può eseguire l'aritmetica dei caratteri che è "0" -> 0, "1" -> "0" + 1, ... in Prolog. – thequark

+0

@thequark: non conosco alcun predicato di questo tipo. 'atom_char/2' può essere usato, ma non sarebbe carino. Si potrebbe anche scrivere un predicato 'digit_int/2' con il valore ASCII di '0' hard-coded (yuck). –

-3

È possibile fornire un esempio di input?

penso che questo potrebbe lavoro:

nat(N)-->number(N). 

Se il problema persiste provare:

nat(N)-->number(N),!. 

L'! è un taglio che ferma l'unificazione. Puoi leggere su di esso in libri/tutorial.

+0

Alcuni esempi di input potrebbero essere expr (E, "2 * 14 + 3", ""). Il codice che hai fornito porta a un messaggio di errore che mi dice che quel numero/3 è una procedura indefinita e che solo il numero/1 è noto. Ho pensato a una clausola DGC per risolvere il mio problema, ma non ero in grado di far funzionare uno. – ubuntudroid

+0

'number/1' è un predicato ordinario, non un predicato DCG. Inoltre, fallisce se il suo input non è ground (è una variabile). –

-1
nat(0). 
nat(N):-nat(N-1). 

Ma si utilizza una sintassi che non conosco (vedere il mio commento sopra).

Problemi correlati