2016-11-27 9 views
3

Gibt es eine Möglichkeit, alle Lösungen anzuzeigen und/oder zu finden, wie viele es in SICSTus Prolog gibt? Zum Beispiel könnte der folgende Code verwendet werden, um das Karteneinfärbungsproblem zu lösen.SICStus Prolog: Finden Sie alle Lösungen

:- use_module(library(clpfd)). 
solve_AUSTRALIA(WA,NT,Q,SA,NSW,V):- 
    domain([WA,NT,Q,SA,NSW,V], 1, 4),%colours represented by integers from 1 to 4 
    WA #\= NT, 
    WA #\= SA, 
    NT #\= SA, 
    NT #\= Q, 
    SA #\= Q, 
    SA #\= NSW, 
    SA #\= V, 
    Q #\= NSW, 
    NSW #\= V, 
    labeling([],[WA,NT,Q,SA,NSW,V]). 

Im Moment Ich schreibe ; jedes Mal, weitere Lösungen zu sehen, bis Prolog nicht sagt. Gibt es eine Möglichkeit, Prolog zu sagen, um alle Lösungen auf einmal zu zeigen, oder besser, eine Art, wie ich dort finden kann. Wie Prolog mir sagt gibt es fünf Lösungen für das Problem.

+0

Sie können versuchen, 'zu verwenden findall/3',' findall/4 ',' bagof/3' oder 'SETOF/3'. Sie sind sich ähnlich. Beispielsweise möchten Sie Ihr Lösungsprädikat in 'findall (+ Templage,: Solution, -Bag) 'und den ursprünglichen Datensatz als' Template' und die kollektive Lösung als '-Bag' setzen. –

+0

Ein genereller Tipp für clpfd in SICStus: Sagen Sie 'assert (clpfd: full_answer)' an der Toplevel, um die vollständige Antwort einschließlich aller Einschränkungen zu erhalten! – false

Antwort

3

Folgendes ist zum Zählen der Anzahl der Antworten. Wenn Sie eine Abfrage stellen oder ein Prädikat ausführen, erhalten Sie Antworten von Prolog. Manchmal sind diese Antworten Lösungen, können mehr als eine Lösung, unendlich viele Lösungen und manchmal sogar gar keine Lösung enthalten.

Der einfachste Weg zu gehen ist zu sagen findall(t, Goal_0, Ts), length(Ts, N). Der einzige Nachteil ist, dass dies Platz erfordert, der proportional zur Anzahl der gezählten Antworten ist.

Wenn Sie einen Schritt weiter gehen wollen, brauchen Sie eine Art Zähler. Derzeit in SICStus 4.3.3 können Sie dies wie so tun:

:- meta_predicate count_answers(0, ?). 
:- meta_predicate count_answers1(0, +, ?). % internal 

:- use_module(library(types),[must_be/4]). 

:- use_module(library(structs), 
     [new/2, 
      dispose/1, 
      get_contents/3, 
      put_contents/3]). 

count_answers(G_0, N) :- 
    ( nonvar(N) 
    -> must_be(N, integer, count_answers(G_0, N), 2) 
    ; true 
    ), 
    new(unsigned_64, Ref), 
    call_cleanup(count_answers1(G_0, Ref, N), dispose(Ref)). 

count_answers1(G_0, Ref, N) :- 
    ( call(G_0), 
     get_contents(Ref, contents, N0), 
     N1 is N0+1, 
     put_contents(Ref, contents, N1), 
     fail 
    ; get_contents(Ref, contents, N) 
    ). 

Siehe this answer wie Zähler können in anderen Systemen implementiert werden. Beispiel für die Verwendung:

| ?- count_answers(member(_,"abcde"),Ans). 
Ans = 5 ? ; 
no 
Verwandte Themen