Aggregat / 3 in Swi-Prolog

8

Ich muss alle X , diese some_predicate(X) und dort wirklich viele solcher X zählen. Was ist der beste Weg, das zu tun?

Der erste Hinweis ist es, alles zu finden, zu einer Liste zu addieren und die Länge zurückzugeben.

%Vor%

( permutation/2 ist nur ein Beispiel, das zeigt, dass es viele Varianten gibt und es eine schlechte Möglichkeit ist, alles zu sammeln)

Offensichtlich habe ich Stack-Overflow.

%Vor%

Dann versuche ich findall zu setof zu ersetzen und nichts ändert sich.

Endlich habe ich % co_de gegründet % (klickbare) Prädikate und versuchen, sie zu verwenden.

%Vor%

Es ist alles falsch, denke ich. Ich bevorzuge etwas wie

%Vor%

1) Was mache ich falsch?

2) Wie kann ich ein Prädikat angeben, um die richtige Antwort zu erhalten?

    
ДМИТРИЙ МАЛИКОВ 08.05.2011, 21:00
quelle

3 Antworten

8

Verwenden Sie eine existentiell quantifizierte Variable, wie Sie es mit setof tun würden:

%Vor%     
Fred Foo 08.05.2011, 21:13
quelle
3

In SWI-Prolog gibt es eine viel effizientere Version, die auch das Sperren des globalen Speichers verhindert. Wenn Sie einfach nb_setval und nb_getval verwenden, erhalten Sie mindestens die dreifache Leistung (mehr beim Multithreading). Vor kurzem noch ging es darum, Lösungen zu zählen. Als Basis der Aggregation ist es ein offensichtlicher Punkt beim Lernen von Prolog. Um den Effizienzgewinn zu bewerten, verwenden wir diese monothread semantisch äquivalenten Aufrufe:

%Vor%

Auf meinem System bekomme ich

%Vor%     
CapelliC 27.09.2011 15:11
quelle
2

Es gibt auch aggregate_all/3 :

%Vor%

Was Laufzeit- und Stack-Überläufe betrifft, scheint es jedoch genauso gut für Ihre findall + length -Lösung zu funktionieren:

%Vor%

Sie können die Lösungen mit assert / retract zählen, dies ist ziemlich langsam, vermeidet aber das "out of stack" -Problem:

%Vor%     
Kaarel 08.05.2011 21:14
quelle

Tags und Links