prolog - SICStus 序言 : Find all solutions

标签 prolog sicstus-prolog

有没有一种方法可以显示所有解决方案和/或找到 ICSTus 序言中有多少解决方案?例如,下面的代码可能用于解决 map 着色问题。

:- 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]).

目前,我正在输入 ;每次看到进一步的解决方案,直到 Prolog 说不。有没有办法告诉 prolog 一次显示所有解决方案,或者更好的是,我可以找到有多少解决方案。就像序言告诉我这个问题有五种解决方案。

最佳答案

以下是计算答案的数量。当您提出查询或执行谓词时,您从 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)
   ).

this answer如何在其他系统中实现计数器。使用示例:
| ?- count_answers(member(_,"abcde"),Ans).
Ans = 5 ? ;
no

关于prolog - SICStus 序言 : Find all solutions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40833736/

相关文章:

windows - 从 sictus prolog pl 文件窗口创建一个独立的 exe 文件

prolog - SICStus Prolog 中的 current_predicate

prolog - SICStus Prolog 垃圾收集跟踪消息

prolog - 有没有办法检查序言中的元素是否为 bool 值?

prolog - 如何计算每个数字的频率?

prolog - 卡住/2 的意外行为

prolog - 内置 Prolog 谓词的性能 (is)/2

prolog - 自反传递闭包的定义

list - 使用 Prolog 读取记录列表并执行有关先前记录的持续计算

prolog - 如何声明两个列表具有相同的长度?