Wykorzystanie zbędnych celów w zapytaniach

12

(Za sugestią @repeat ) Zastanów się nad zapytaniem czystego programu 1 ?- G_0. Jaki użytek z tego miałoby zapytanie ?- G_0, G_0.?

Przypisy
1 Brak tablicowania (dla bezpieczeństwa), ograniczenia są OK.
Poprzedni post na ten temat.

fałszywe
źródło
Kwadratowa liczba wyników?
Willem Van Onsem
1
Rozumiem, że żadna informacja o stanie nie jest zachowana po kolejnym uruchomieniu bramki. Innymi słowy, odmiana pytania jest niedozwolona, ​​np. Czy ?- G_0(State), G_0(State).również na stosie nie jest przekazywany stan od wyniku pierwszego gola do drugiego gola?
Guy Coder
1
G_0może być dowolny (czysty) cel, w tym, powiedzmyG_0 = append(Xs,Ys,Zs)
fałszywy
1
@GuyCoder: wymagane jest połączenie. (Przy G_0;G_0jednym można przetestować działania niepożądane lub problemy z wydajnością / buforowaniem / tabelowaniem)
false
1
BTW, zamiast G_0(State),G_0(State)jednego raczej piszecall(G_1,State), call(G_1,State)
false

Odpowiedzi:

3

Zapytanie ?- G_0, G_0.pomaga zidentyfikować zbędne odpowiedzi?- G_0.

Aby to zrobić, wystarczy porównać liczbę odpowiedzi ?- G_0.z liczbą odpowiedzi z ?- G_0, G_0.. Nie trzeba przechowywać tych odpowiedzi (co i tak jest częstym źródłem błędów). Wystarczy dwie liczby całkowite! Jeśli są równe, nie ma redundancji. Ale jeśli ?- G_0, G_0.ma więcej odpowiedzi, istnieje pewna redundancja. Oto przykład:

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

... a teraz naprawmy to:

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

Nie trzeba ręcznie sprawdzać związanych z tym ograniczeń.

Można to dodatkowo rozszerzyć, gdy wyraźnie szukamy zbędnych odpowiedzi tylko przy użyciu call_nth/2.

?- G_0, call_nth(G_0, 2).
fałszywe
źródło
1

Rozważ zapytanie o czysty program1? - G_0. Jaki pożytek z tego miałoby zapytanie? - G_0, G_0. mieć?

Nie widzę żadnej przydatności drugiego celu, zwłaszcza gdy włączona jest optymalizacja rekurencji ogona ( optymalizacja ostatniego połączenia ) .

Mógłbym zrozumieć problem GC (przepełnienie stosu / sterty), gdy zapytanie jest zachłanne na zasoby i powyższe opcje są WYŁĄCZONE (np. Podczas debugowania).

Myślę, że drugie wywołanie jest redundantne (dla czystego programu) i powinno zostać wyeliminowane przez kompilator.

Anton Daniłow
źródło