2016-04-12 1 views
0

Ich bin mit SWI-Prolog arbeiten, um die Liste aller verschiedenen ganzen Zahlen zwischen 5 und 10 zu erhalten clpfd erzeugen:clpfd - erzeugen die Liste aller ganzen Zahlen zwischen 5 und 10

q1(Answer) :- 
    length(Xs, Answer), 
    Xs ins 0..20, 
    chain(Xs, #<), 
    maplist(q1constraints, Xs). 

q1constraints(X) :- 
    X #>= 5, 
    X #=< 10. 

Art der Arbeiten, aber erzeugt eine Lösung für jede der Längen 0, 1, ... 6 und legt dann eine Lösung von Länge 7 sucht:

?- q1(Answer). 
Answer = 0 ; 
Answer = 1 ; 
Answer = 2 ; 
Answer = 3 ; 
Answer = 4 ; 
Answer = 5 ; 
Answer = 6 ; 
<hangs> 

gibt es ein guter Weg, um die Liste der alle ganzen Zahlen zu erzeugen, die die befriedigen gewünschte Einschränkungen?

+0

Eine Liste? Oder sie durch Backtracking generieren? Und was meinst du mit "eindeutig", genau? Warum die 'Länge/2'? Warum die "ins 0..20"? Ich habe das Gefühl, dass du nicht erklärst, was du zu tun versuchst. –

+0

Ich möchte aus Einschränkungen die Liste [5, 6, 7, 8, 9, 10] generieren und dann zählen, wie viele Elemente darin enthalten sind. Die Constraints können reicher sein, zum Beispiel möchte ich eine Form von "even" Constraint hinzufügen, möglicherweise "X mod 2 # = 0", was [6, 8, 10] erzeugen sollte. Der Listenoperator kann reicher sein, zum Beispiel möchte ich "sum" anstelle von "count" sagen. –

+0

PS. Deutlich, da mir Listen wie [5, 5, 5, 5, 5, 6] egal sind. –

Antwort

2

Hier ist, was Ihr Programm tut:

  1. Erstellen Sie eine Liste Längen zu erhöhen, mit einer leeren Liste Start
  2. Für jedes Element X in der Liste, stellen eine Einschränkung, dass X in [0, 20]
  3. Stellen Sie für die gesamte Liste eine Einschränkung, dass Werte in der Größenordnung streng zunehmen
  4. Legen Sie für jedes Element in der Liste eine zusätzliche Einschränkung, die X ist in [5, 10].

Sie fragen dann nach der Länge der generierten Liste.

Es gibt 6 Werte in [0, 20] und in [5,10]: 5, 6, 7, 8, 9, 10. Für die leere Liste, die Sie zuerst generieren, gibt es keine eingeschränkten Variablen; Für die Liste mit 1 Variable gäbe es 6 mögliche Werte der Variablen, aber Sie fragen nicht nach diesen Werten, sondern nur nach der Länge der Liste; Für die Liste mit 2 Variablen haben Sie 5 mögliche Kombinationen: {5,6}, {6,7}, ..., {9,10}, aber Sie fragen nicht nach ihnen, nur nach dem Länge der Liste.

Schließlich können Sie mit 7 Werte auflisten. Da jedes Element nur 6 Werte haben kann, gibt es keine Lösungen.

Also was ist dein Ziel hier? Vielleicht solltest du versuchen, es besser zu erklären. Um alle Werte zwischen 5 und 10 durch Backtracking zu erhalten, könnten Sie sagen: between(5, 10, X), oder mit CLPFD, X in 5..10, label([X]). Wenn es keines von beiden ist, müssen Sie Ihre Frage neu schreiben.

3

Ihre Frage ist mir nicht so klar. Aber ich werde versuchen:

?- length(Xs,6), Xs ins 5..10, chain(Xs, #<), Xs = [5|_], last(Xs, 10). 
Xs = [5, 6, 7, 8, 9, 10]. 

Beachten Sie, dass mit diesen Elementen ist es notwendig, die Länge der Liste zuerst zu beheben. Ansonsten:

?- length(Xs,N), Xs ins 5..10, chain(Xs, #<), Xs = [5|_], last(Xs, 10). 
Xs = [5, 10], N = 2 ; 
Xs = [5, _A, 10], N = 3, _G7292 in 6..9 ; 
Xs = [5, _A, _B, 10], N = 4, _A in 6..8,_A#=<_B+ -1,_B in 7..9 ; 
Xs = [5, _A, _B, _C, 10], N = 5, _A in 6..7, _A#=<_B+ -1, _B in 7..8,_B#=<_C+ -1, _C in 8..9 ; 
Xs = [5, 6, 7, 8, 9, 10], N = 6 ; 
** LOOPS ** 

In der Tat, auch die (ins)/2 ist nicht erforderlich:

?- length(Xs,6), chain(Xs, #<), Xs = [5|_], last(Xs, 10). 
Xs = [5, 6, 7, 8, 9, 10]. 
+0

Danke für die Antwort. Die Frage ist wörtlich "wie viele positive [gerade] ganze Zahlen zwischen 5 und 10 sind". Wenn man die Länge als Eingabe übergibt, wird der Zweck vereitelt :) Ich habe "sogar" Prädikat hinzugefügt, um es etwas interessanter zu machen. –

Verwandte Themen