2012-01-21 10 views
6

mi sono imbattuto in questa valutazione numero naturale di numeri logici in un tutorial e mi sta dando un po 'di mal di testa:Converti numero di Peano s (N) per intero in Prolog

natural_number(0). 
natural_number(s(N)) :- natural_number(N). 

La regola afferma grosso modo che: se N è 0 è naturale, se non proviamo a inviare il contenuto di s/1 indietro in modo ricorsivo alla regola finché il contenuto non è 0, quindi è un numero naturale se non è così.

Così ho provato la realizzazione logica di cui sopra, pensato a me, questo funziona bene se voglio rappresentare s(0) come 1 e s(s(0)) come 2, ma I'd piace essere in grado di convertire s(0)-1 invece.

Ive pensato della regola di base:

sToInt(0,0). %sToInt(X,Y) Where X=s(N) and Y=integer of X 

Così qui è la mia domanda: Come posso convertire i (0) a 1 e S (s (0)) per 2?

è stato risposto

Edit: ho modificato la regola di base per l'attuazione, che la risposta ho accettato mi ha segnalato in direzione:

decode(0,0). %was orignally decode(z,0). 
decode(s(N),D):- decode(N,E), D is E +1. 

encode(0,0). %was orignally encode(0,z). 
encode(D,s(N)):- D > 0, E is D-1, encode(E,N). 

Così ora posso usarlo come avrei voluto a, grazie a tutti!

+0

(a) E' compiti? (b) Questo è un problema standard - dovresti riuscire a trovarlo in qualsiasi tutorial o libro di testo sulla programmazione logica. – Marcin

+0

a) No, sto solo cercando di imparare Prolog b) Lo si potrebbe pensare, ma ho passato la metà migliore di un giorno cercando di trovare una risposta a questa domanda senza alcun risultato – shaungus

risposta

1

Questo è un compito di serie - una soluzione è qui: http://www.docstoc.com/docs/82593705/Prolog-%E2%80%93-Family-Tree (pagina 109).

L'intuizione fondamentale è che il valore di s(N) è 1+ il valore di N, e che se N è 0, il valore è 0.

+0

Grazie per averlo chiarito, Sembra che la maggior parte del mio problema fosse che s (N) è chiamato un numero di peano :) – shaungus

+0

@shaungus: Pur sapendo ciò, ho trovato difficoltà a cercare una risposta. In questo caso, i libri sono tuoi amici. – Marcin

5

Ecco un'altra soluzione che funziona "in entrambe le direzioni" utilizzando library(clpfd) di SWI, YAP, o SICStus

:- use_module(library(clpfd)). 

natsx_int(0, 0). 
natsx_int(s(N), I1) :- 
    I1 #> 0, 
    I2 #= I1 - 1, 
    natsx_int(N, I2). 
2

No problemo con nest_right/4 in tandem con Prolog lambdas!

:- use_module(library(lambda)). 
:- use_module(library(clpfd)). 

:- meta_predicate nest_right(2,?,?,?). 
nest_right(P_2,N,X0,X) :- 
    zcompare(Op,N,0), 
    ord_nest_right_(Op,P_2,N,X0,X). 

:- meta_predicate ord_nest_right_(?,2,?,?,?). 
ord_nest_right_(=,_,_,X,X). 
ord_nest_right_(>,P_2,N,X0,X2) :- 
    N0 #= N-1, 
    call(P_2,X1,X2), 
    nest_right(P_2,N0,X0,X1). 

query di esempio:

?- nest_right(\X^s(X)^true,3,0,N). 
N = s(s(s(0))).     % succeeds deterministically 

?- nest_right(\X^s(X)^true,N,0,s(s(0))). 
N = 2 ;       % succeeds, but leaves behind choicepoint 
false.       % terminates universally