2011-08-24 6 views
6

Me gustaría utilizar predicados como:Prolog - Lista de generación de números herraje dado gama

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

de significado:

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]). 

cómo codificar en Prolog muy bien (teniendo en rendimiento de la solución cuenta - profundidad de recursión, etc.)?

Se espera que la solución se ejecute en GNU-Prolog.

P.S. Pregunta inspirada con this question.

Respuesta

11

SWI-Prolog tiene el predicado between/3. entonces lo llamarías entre (0,5, X) para obtener los resultados que mostraste arriba. Este predicado parece que esto se implementa en C embargo.

Si tenemos que escribirlo en prólogo puro (y la velocidad & el espacio no es un factor), podría intentar lo siguiente.

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

¿Es aplicable a 'domain()'? –

+0

¿Qué es el dominio exactamente? No podría decir lo que esperaba dom_range hacer en el escenario anterior. ¿Es esta otra manera de pasar argumentos al rango? dom_range (Out, [Low, High]): - range (Out, Low, High). – DaveEdelstein

+0

He leído sobre "dominio" en [este tutorial] (http://wazniak.mimuw.edu.pl/index.php?title=Sztuczna_inteligencja/SI_Modu%C5%82_3_-_Wnioskowanie_w_PROLOG-u), pero estoy inseguro sobre los detalles, porque soy el principiante de Prolog. Mientras revisaba el manual de Gnu-Prolog, encontré [fd_domain/3] (http://www.gprolog.org/manual/gprolog.html#htoc321), especificado como [fd_domain (+ fd_variable_list_or_fd_variable, + integer, + integer) ] (http://www.gprolog.org/manual/gprolog.html#htoc321) - ¿Cómo piensas? ¿Podría ser otra solución? –

0

range en GNU-Prolog se pueden resolver con dominios finitos

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

No sé si dom_range(X,L,H) :- fd_domain(X,L,H).

P.S. Al jugar con dominios finitos, es posible que desee utilizar fd_set_vector_max/1

9

La respuesta de Dave es casi perfecta: no hay comprobación para ver si < es bajo. He añadido una condición y ahora funciona bien (de lo contrario, genera números de menor a infinito):

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

Espero que ayude!

Cuestiones relacionadas