【问题标题】:SICStus Prolog: Find all solutionsSICStus Prolog:查找所有解决方案
【发布时间】:2016-11-27 20:49:52
【问题描述】:

有没有一种方法可以显示所有解决方案和/或找出 SICTus prolog 中有多少解决方案?例如,下面的代码可能用于解决地图着色问题。

:- 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/3findall/4bagof/3setof/3。它们是相似的。例如,您要做的是将解决方案谓词放在findall(+Templagte, :Solution, -Bag),原始数据集为Template,集体解决方案为-Bag
  • SICStus 中 clpfd 的一般提示:在顶层说 assert(clpfd:full_answer) 以获得包括所有附加约束在内的完整答案!

标签: prolog sicstus-prolog


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多