Uso de objetivos redundantes en consultas

12

(Por sugerencia de @repeat ) Considere una consulta de un programa puro 1 ?- G_0. ¿De qué sirve si la consulta ?- G_0, G_0.tuviera alguna ?

Notas al pie
1 Sin tabulación (para estar seguro), las restricciones están bien.
Publicación anterior sobre el tema.

falso
fuente
¿Cuadrar el número de resultados?
Willem Van Onsem
1
Supongo que no se conserva información del estado de la ejecución consecutiva de la meta. En otras palabras, no se permite una variación de la pregunta, por ejemplo, ¿ ?- G_0(State), G_0(State).tampoco se pasa ningún estado en la pila desde el resultado del primer gol al segundo gol?
Guy Coder
1
G_0puede ser cualquier objetivo (puro), incluido, por ejemploG_0 = append(Xs,Ys,Zs)
falso
1
@GuyCoder: se requiere conjunción. (Con G_0;G_0uno podría probar los efectos secundarios o problemas de rendimiento / almacenamiento en caché / tabeling)
falso
1
Por cierto, en lugar de G_0(State),G_0(State)uno más bien escribecall(G_1,State), call(G_1,State)
falso

Respuestas:

3

La consulta ?- G_0, G_0.ayuda a identificar respuestas redundantes de?- G_0.

Para hacerlo, es suficiente comparar el número de respuestas de ?- G_0.con el número de respuestas de ?- G_0, G_0.. No es necesario almacenar esas respuestas (que de todos modos es una fuente frecuente de errores). ¡Solo dos enteros son suficientes! Si son iguales, entonces no hay redundancia. Pero si ?- G_0, G_0.tiene más respuestas, entonces hay algo de redundancia. Aquí hay un ejemplo:

p(f(_,a)).
p(f(b,_)).

?- p(X).
   X = f(_A, a)
;  X = f(b, _A).  % two answers

?- p(X), p(X).
   X = f(_A, a) 
;  X = f(b, a)
;  X = f(b, a)
;  X = f(b, _A).   % four answers
                   % thus p(X) contains redundancies

... y ahora arreglemos esto:

p(f(B,a)) :-
   dif(B, b).
p(f(b,_)).

?- p(X).
   X = f(_A, a), dif(_A, b)
;  X = f(b, _A).

?- p(X), p(X).
   X = f(_A, a), dif(_A, b), dif(_A, b).
;  X = f(b, _A).    % again two answers, thus no redundancy

No es necesario inspeccionar manualmente las restricciones involucradas.

Esto puede extenderse aún más cuando estamos buscando explícitamente respuestas redundantes solo usando call_nth/2.

?- G_0, call_nth(G_0, 2).
falso
fuente
1

Considere una consulta de un programa puro1? - G_0. ¿De qué serviría si fuera la consulta? - G_0, G_0. ¿tener?

No veo ninguna utilidad del segundo objetivo, especialmente cuando la optimización de recursión de cola ( optimización de última llamada ) está activada .

Podría darme cuenta de un problema de GC (desbordamiento de pila / montón) cuando la consulta es codiciosa de recursos y las opciones anteriores están DESACTIVADAS (por ejemplo, al depurar).

Creo que la segunda llamada es redundante (para un programa puro) y el compilador debería eliminarla.

Anton Danilov
fuente