zasadzie piszesz program czek dla globalnej implikację:
forall N, if N < 10 then N > 5
i chcesz wiedzieć, dla których domena N
że trzyma.
Teraz poprawnie przepisać że w prologu jak:
\+ (N < 10, \+ (N > 5)).
Ale jeśli spróbujesz dać, że zapytanie do prolog tłumacza, to wyświetli się błąd:
?- \+ (N < 10, \+ (N > 5)).
ERROR: </2: Arguments are not sufficiently instantiated
ponieważ argumenty <
nie są tworzone instancjami. Zdarza się to samo z prostym zapytaniem, takim jak N < 3
. Oczywiście, jeśli instancję przed zapytania, problem zniknie:
?- N=5, \+ (N < 10, \+ (N > 5)).
false.
(oświadczenie nie trzymać dla N = 5)
?- N=6, \+ (N < 10, \+ (N > 5)).
N = 6.
(ale to zachodzi dla n = 6) .
Można również umieścić predykat, który generuje wiele zadań dla N
poprzez backtracking, zamiast tego N=6
:
?- between(1, 12, N), \+ (N < 10, \+ (N > 5)).
N = 6 ;
N = 7 ;
N = 8 ;
N = 9 ;
N = 10 ;
N = 11 ;
N = 12.
ale dla dużej domeny, która będzie bardzo nieefektywne (będzie to wymagało backtracking dla każdego elementu domeny).
Jeśli chcesz uzyskać informacje na temat domen skończonych (tzn. Liczb całkowitych), możesz skorzystać z biblioteki CLPFD, zgodnie z sugestią @lurker. To podejście jest bardziej wydajne, ponieważ zawiera reguły dotyczące wnioskowania o odstępach czasu, przecinania w interwałach i wiele innych.
Trzeba zastąpić <
, >
, ,
, \+
z CLP operatorów #<
, #>
, #/\
, #\
. Spróbujmy go:
?- use_module(library(clpfd)).
?- #\ (N #< 10 #/\ #\ (N #> 5)).
N+1#=_G11193,
N#>=6#<==>_G11205,
10#>=_G11193#<==>_G11217,
_G11217 in 0..1,
_G11217#/\_G11244#<==>0,
_G11244 in 0..1,
#\_G11205#<==>_G11244,
_G11205 in 0..1.
że może być nieco trudne do odczytania, ale wśród wielu innych rzeczy, to mówi wam odpowiedź, której szukasz, że to domena N: N #>= 6
.
Opcja '2' and '>/2' operatorzy wymagają, aby wszystkie argumenty mają specyficzne wartości (są instancja) w celu podjęcia pracy. Więc jeśli 'N' nie ma wartości (nie jest * instancja *), to' N <10' wygeneruje ten błąd. Jeśli próbujesz wygenerować możliwe wartości z pewnymi ograniczeniami, możesz użyć biblioteki CLPFD, możesz użyć 'N # <10', itd. – lurker
@lurker Ok Widzę. Jak zmienić kod tak, aby wyprowadzał wszystkie możliwe liczby całkowite? I nie tylko sprawdza, czy argument spełnia warunek? Czy to możliwe? – akalikin
@lurker ok, wielkie dzięki – akalikin