Utilisation d'objectifs redondants dans les requêtes


12

(Sur la suggestion de @repeat ) Considérons une requête d'un programme pur 1 ?- G_0. Quelle utilité aurait le cas échéant la requête ?- G_0, G_0.?

Notes de bas de page
1 Pas de dépôt (pour être sûr), les contraintes sont OK.
Article précédent sur le sujet.


La quadrature du nombre de résultats?
Willem Van Onsem

1
Je suppose qu'aucune information d'état n'est préservée de l'exécution consécutive de l'objectif. En d'autres termes, une variation de la question n'est pas autorisée, par exemple, ?- G_0(State), G_0(State).aucun état n'est passé sur la pile du résultat du premier but au deuxième but?
Guy Coder

1
G_0peut être n'importe quel objectif (pur), y compris, disonsG_0 = append(Xs,Ys,Zs)
faux

1
@GuyCoder: la conjonction est requise. (Avec G_0;G_0on pourrait tester les effets secondaires ou les problèmes de performances / de mise en cache / tabulation)
faux

1
BTW, au lieu d' G_0(State),G_0(State)un écrit plutôtcall(G_1,State), call(G_1,State)
faux

Réponses:


3

La requête ?- G_0, G_0.permet d'identifier les réponses redondantes de?- G_0.

Pour ce faire, il suffit de comparer le nombre de réponses de ?- G_0.avec le nombre de réponses de ?- G_0, G_0.. Pas besoin de stocker ces réponses (ce qui est de toute façon une source fréquente d'erreurs). Deux entiers suffisent! S'ils sont égaux, il n'y a pas de redondance. Mais si ?- G_0, G_0.a plus de réponses, il y a une certaine redondance. Voici un exemple:

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

... et maintenant corrigeons ceci:

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

Pas besoin d'inspecter manuellement les contraintes impliquées.

Cela peut être étendu lorsque nous recherchons explicitement des réponses redondantes uniquement en utilisant call_nth/2.

?- G_0, call_nth(G_0, 2).

1

Considérons une requête d'un programme pur1? - G_0. À quoi bon, le cas échéant, la requête? - G_0, G_0. avoir?

Je ne vois aucune utilité du deuxième objectif, surtout quand optimisation de la récursivité de queue ( optimisation du dernier appel ) est activée .

Je pourrais réaliser un problème GC (débordement de pile / tas) lorsque la requête est gourmande en ressources et que les options ci-dessus sont désactivées (par exemple lors du débogage).

Je pense que le deuxième appel est redondant (pour le programme pur) et devrait être éliminé par le compilateur.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.