2011-08-24 14 views
6

Mi piacerebbe usare predicati come:Prolog - Lista di generazione dei numeri di raccordo determinato intervallo

range(X,0,5) 
range(X,4,200) 
range(X,-1000000,1000000) 
dom_range(X,-1000000,1000000) 

di significato:

range(X,0,5) :- member(X,[0,1,2,3,4,5]). 
range(X,4,200) :- member(X,[4,5,6...198,199,200]). 
range(X,-1000000,1000000) :- member(X,[-1000000,...,1000000]). 
dom_range(X,-1000000,1000000) :- domain(X, [-1000000,...,1000000]). 

Come codice in Prolog bene (prendendo prestazioni soluzione in conto - profondità della ricorsione, ecc.)?

Si prevede che la soluzione funzioni su GNU-Prolog.

P.S. Domanda ispirata a this question.

risposta

11

SWI-Prolog ha il predicato between/3. quindi lo chiameresti come tra (0,5, X) per ottenere i risultati che hai mostrato sopra. Questo predicato sembra che questo sia implementato in C sebbene.

Se dovessimo scriverlo in puro prologo (e la velocità & non è un fattore), si potrebbe provare questo seguendo.

range(Low, Low, High). 
range(Out,Low,High) :- NewLow is Low+1, range(Out, NewLow, High). 
+0

È applicabile a 'domain()'? –

+0

cos'è esattamente il dominio? Non potevo dire cosa ti aspettavi da dom_range nello scenario sopra. questo è solo un altro modo per passare argomenti a portata di mano? dom_range (Out, [Low, High]): - range (Out, Low, High). – DaveEdelstein

+0

Ho letto di "dominio" in [questo tutorial] (http://wazniak.mimuw.edu.pl/index.php?title=Sztuczna_inteligencja/SI_Modu%C5%82_3_-_Wnioskowanie_w_PROLOG-u), ma io sono incerto sui dettagli, perché sono principiante di Prolog. Durante il controllo sul manuale di Gnu-Prolog ho trovato [fd_domain/3] (http://www.gprolog.org/manual/gprolog.html#htoc321), specificato come [fd_domain (+ fd_variable_list_or_fd_variable, + intero, + intero) ] (http://www.gprolog.org/manual/gprolog.html#htoc321) - come pensi? Potrebbe essere un'altra soluzione? –

0

range a Gnu-Prolog può essere risolto con domini finiti

range(X,Low,High) :- fd_domain(X,Low,High). 

Non so se dom_range(X,L,H) :- fd_domain(X,L,H).

P.S. Quando giochi con domini finiti, ti potrebbe piacere usare fd_set_vector_max/1

9

La risposta di Dave è quasi perfetta: non ci sono controlli per vedere se basso < alto. Ho aggiunto una condizione e ora funziona benissimo (altrimenti si genera numeri dal basso verso l'infinito):

range(Low, Low, High). 
range(Out,Low,High) :- NewLow is Low+1, NewLow =< High, range(Out, NewLow, High). 

Speranza che aiuta!

Problemi correlati