2012-04-12 15 views
2

Ich versuche Contrain X zu verwenden, um kein Wert in einer Liste zu sein.Verwendung von in_set/2 Constraint

Vom SICStus Prolog manual:

?X in_set +FDSet 

ich kann nicht herausfinden, wie man eine Liste in eine FDSet konvertieren, though. Ich habe eine Liste von ganzen Zahlen [2,3,8,9] und ich möchte die Domäne der Variablen X einschränken, um nicht in dieser Liste zu sein. Wie mache ich das? Vielen Dank.

Antwort

4

Gemessen an der documentation, was ist mit ? Sie können in eine FDSet übersetzen, dann bauen Sie Komplement, dann post in_set/2. Wenn Ihre Version nicht über verfügt, können Sie die Liste problemlos in einen normalen Domänenausdruck konvertieren und anschließend eine negierte in/2-Einschränkung bereitstellen. In Ihrem Beispiel, würden Sie dann Post:

#\ X in {2}\/{3}\/{8}\/{9} 

und Sie nur die Beziehung zwischen einer Liste beschreiben und eine Domäne Expression von Singletons besteht, das leicht:

list_domain([I|Is], Dom) :- 
     foldl(integer_domain_, Is, {I}, Dom). 

integer_domain_(I, D0, D0 \/ {I}). 

Beispielabfragen:

?- list_domain([1,2,3], Dom). 
Dom = {1}\/{2}\/{3}. 

?- list_domain([1,2,3], Dom), X in Dom. 
Dom = {1}\/{2}\/{3}, 
X in 1..3. 
+0

Worum geht es: 'X in \ ({2} \/{3} \/{8} \/{9})' – false

0

ich ein wie hier implementiert ..

/** Constraint domain to memebers of a list (of numbers only) **/ 

domain_list_constraint(_, []) :- !. 
domain_list_constraint(DomainVar, List) :- member(E, List), 
           (atom(E)->atom_number(E, I), 
           DomainVar #= I; 
           DomainVar #= E). 
+2

Dies ist * generate-and-test * und verwirkt die Macht von Constraints. Der Punkt von "in/2" soll den Bereich einer Variablen deterministisch festlegen. Statt Backtracking (mit 'member/2') sollten Sie die Liste deterministisch in einen Domänenausdruck umwandeln und dann eine einzelne 'in/2'-Bedingung veröffentlichen, um vollständig von den CLP (FD) -Beschränkungen zu profitieren. – mat

+0

hmm ,, hört sich gut an !!! Ich werde sehen, ob ich das umsetzen kann. Danke für den Hinweis. –