SICStus Prolog: найти все решения
Есть ли способ показать все решения и / или узнать, сколько их в прологе SICSTus? Например, приведенный ниже код может быть использован для решения проблемы раскраски карты.
:- 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]).
На данный момент я печатаю ;
каждый раз, чтобы увидеть дальнейшие решения, пока Пролог не скажет нет. Есть ли способ, которым я могу сказать прологу, чтобы он показывал все решения сразу, или, что лучше, способ, которым я могу найти, сколько там. Как говорит пролог, есть пять вариантов решения проблемы.
2 ответа
Ниже приведен подсчет количества ответов. Когда вы задаете запрос или выполняете предикат, вы получаете ответы от Prolog. Иногда эти ответы являются решениями, могут содержать более одного решения, бесконечно много решений, а иногда даже вообще не иметь решения.
Самый простой способ это сказать findall(t, Goal_0, Ts), length(Ts, N)
, Единственным недостатком является то, что для этого требуется пространство, пропорциональное количеству подсчитанных ответов.
Если вы хотите пойти еще дальше, вам понадобится какой-то счетчик. В настоящее время в SICStus 4.3.3 вы можете сделать это так:
:- 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)
).
Посмотрите этот ответ, как счетчики могут быть реализованы в других системах. Пример использования:
| ?- count_answers(member(_,"abcde"),Ans).
Ans = 5 ? ;
no
Есть ли способ заставить Prolog показывать все решения сразу?
Эта часть вашего вопроса связана с prolog-toplevel . В Prolog IV все ответы (не обязательно решения) показывались по умолчанию. Цикл верхнего уровня пары систем Prolog позволяет войти a, чтобы увидеть все ответы сразу:
- GNU-Prolog (создатель)
- Треалла-Пролог
- Scryer-Prolog