【问题标题】:Get multiple answers from prolog predicate从 prolog 谓词中获得多个答案
【发布时间】:2018-11-29 00:12:26
【问题描述】:

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

foo(Number, Out) :- Number < 10, Out = less_than_ten.
foo(Number, Out) :- Number > 0, Out = more_than_zero.

我如何获得foo 在另一个谓词中给出的所有Out 值,记住它有时会给出一个,有时会给出多个(例如在列表中)?

编辑 - 不太确定我得到的答案是否能回答我的问题,所以我会更具体。使用上述谓词,我可以运行查询 foo(5, Out). 这满足两个规则,所以如果我在 SWI-prolog 中运行它,我会得到这个 -

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

然后我可以输入一个分号让prolog回溯并寻找其他解决方案-

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

因此,如果我在另一个谓词中执行此谓词,在给定 Number = 5 的情况下,如何获取 Out 的所有有效值?

【问题讨论】:

    标签: prolog prolog-setof


    【解决方案1】:

    如果您只考虑整数,您可以选择使用 CLP(FD)。那么你的谓词 foo 可能看起来像这样:

    :- use_module(library(clpfd)).
    
    foo(Nums) :-
       Nums ins 1..9.     % the numbers in the list Nums are 0 < X < 10
    

    你可以使用这个谓词来测试一个数字列表是否在你想要的范围内:

       ?- foo([1,2,3,4,5]).
    yes
       ?- foo([0,1,2,3,4,5]).
    no
       ?- foo([1,2,3,4,5,10]).
    no
    

    如果您想使用它来生成该范围内的整数列表,您必须确保 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 ?
    .
    .
    .
    

    这些答案包含剩余目标(有关详细信息,请参阅CLP(FD) documentation)。如果要查看实际数字,则必须添加一个目标来标记列表:

       ?- 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] ? ;
    .
    .
    .
    

    【讨论】:

      【解决方案2】:

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

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

      A useful guide for different ways to find all solutions to a goal.

      【讨论】:

        猜你喜欢
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多