从prolog谓词获取多个答案

从prolog谓词获取多个答案,prolog,prolog-setof,Prolog,Prolog Setof,假设我有一个谓词,它有时会给我多个输出。像这样- foo(Number, Out) :- Number < 10, Out = less_than_ten. foo(Number, Out) :- Number > 0, Out = more_than_zero. 然后我可以输入一个分号,让prolog回溯并寻找另一个解决方案- ?- foo(5, Out). Out = less_than_ten ; Out = more_than_zero. 因此,如果我在另一个谓词中执行此

假设我有一个谓词,它有时会给我多个输出。像这样-

foo(Number, Out) :- Number < 10, Out = less_than_ten.
foo(Number, Out) :- Number > 0, Out = more_than_zero.
然后我可以输入一个分号,让prolog回溯并寻找另一个解决方案-

?- foo(5, Out).
Out = less_than_ten ;
Out = more_than_zero.

因此,如果我在另一个谓词中执行此谓词,那么如何获得Out的所有有效值,给定的数字=5?

如果您只考虑整数,那么可以选择使用CLP(FD)。那么您的谓词foo可能如下所示:

:- use_module(library(clpfd)).

foo(Nums) :-
   Nums ins 1..9.     % the numbers in the list Nums are 0 < X < 10
如果要使用它生成该范围内的整数列表,必须确保
Nums
是一个列表,以避免实例化错误。您可以通过在查询中为目标长度/2添加前缀来实现这一点:

   ?- length(Nums,_), foo(Nums).
Nums = [] ? ;          % <- no number
Nums = [_A],           % <- one number
_A in 1..9 ? ;
Nums = [_A,_B],        % <- two numbers
_A in 1..9,
_B in 1..9 ? ;
Nums = [_A,_B,_C],     % <- three numbers
_A in 1..9,
_B in 1..9,
_C in 1..9 ?
.
.
.

刚刚找到了回答这个问题的谓词。Prolog有一个内置谓词
bagof(Template,Goal,Bag)
,它将
Goal
谓词的
Template
参数与
Bag
参数统一起来(不确定这是正确的Prolog行话!)。因此,在问题的示例中,使用
bagof(Out,foo(5,Out),Outputs)。
,这将把
Out
的解决方案列表与
Outputs
统一起来。在SWI prolog中运行查询:

4 ?- bagof(Out, foo(5, Out), Outputs).
Outputs = [less_than_ten, more_than_zero].

   ?- length(Nums,_), foo(Nums).
Nums = [] ? ;          % <- no number
Nums = [_A],           % <- one number
_A in 1..9 ? ;
Nums = [_A,_B],        % <- two numbers
_A in 1..9,
_B in 1..9 ? ;
Nums = [_A,_B,_C],     % <- three numbers
_A in 1..9,
_B in 1..9,
_C in 1..9 ?
.
.
.
   ?- length(Nums,_), foo(Nums), label(Nums).
Nums = [] ? ;
Nums = [1] ? ;
Nums = [2] ? ;
Nums = [3] ? ;
.
.
.
Nums = [1,1] ? ;
Nums = [1,2] ? ;
Nums = [1,3] ? ;
.
.
.
Nums = [9,9] ? ;
Nums = [1,1,1] ? ;
Nums = [1,1,2] ? ;
.
.
.
4 ?- bagof(Out, foo(5, Out), Outputs).
Outputs = [less_than_ten, more_than_zero].