【问题标题】:Capture values from one list in Prolog and add to another list从 Prolog 中的一个列表中捕获值并添加到另一个列表
【发布时间】:2017-05-08 02:30:03
【问题描述】:

我正在尝试在 prolog 中开发代码以捕获频率为 0 的项目。看示例,元组:

[[1,31],[2,0],[3,21],[4,0],[5,0]]

其中每个元素都是其他元素,每个元素有 2 个元素,因此应该捕获的元素是 2、4 和 5,频率为 0。下面的代码代表了这个想法:

match([],_).
match([[A,Y]|Tail],[A|Tail2]):- Y==0,match(Tail,[Tail2|A]),!.
match([[_,_]|Tail],X):- match(Tail,X).

传递了两个参数:一个包含一组目标值和频率的元组,

(["Target value", "frequency"], ["target value", "frequency"], ...]

第二个参数是一个变量,它接收目标元素。但是,我不得不开发代码的抽象是不正确的,因为结果并不如预期的那样。我一步一步地了解,修改了几件事,结果总是一样的......无论如何都会返回一个只有2个元素的列表(即使只有一个频率为0的目标)。

3 个频率目标 0 的示例:

?- match([[1,31],[2,0],[3,312],[4,0],[5,0]],X).
X = [2|4].

本例的预期结果:X = [2,4,5]。

以 1 个频率目标 0 为例:

?- match([[1,31],[2,0],[3,312],[4,312],[5,123]],X).
X = [2|_9998].

本例的预期结果:X = [2]。

有人可以帮助我吗?

【问题讨论】:

    标签: list prolog logic tuples paradigms


    【解决方案1】:

    您可以选择使用 DCG 来描述结果列表,如下所示:

    match(Pairs,ZFs) :-           % the items with frequency 0
       phrase(zeros(Pairs),ZFs).  % are described by zeros//1
    
    zeros([]) -->                 % the empty list
       [].                        % contains no items
    zeros([[I,0]|Is]) -->         % if the frequency is 0
       [I],                       % the item is in the list
       zeros(Is).                 % the same for the remaining items
    zeros([[I,F]|Is]) -->         % if the frequency
       {dif(F,0)},                % is not 0, the item isn't in the list
       zeros(Is).                 % the same for the remaining items
    

    因此,您帖子中的两个示例查询产生了所需的结果:

       ?- match([[1,31],[2,0],[3,21],[4,0],[5,0]],X).
    X = [2,4,5] ? ;
    no
       ?- match([[1,31],[2,0],[3,312],[4,312],[5,123]],X).
    X = [2] ? ;
    no
    

    【讨论】:

      【解决方案2】:

      你非常接近!只有两个小问题:

      • 目前,当传递一个空列表时,您说结果可以是任何东西 (_)。我非常怀疑这是您想要的;空列表的输出也应该是空列表。
      • 第二个子句中的递归调用不正确。你想要的结果是A,后跟递归调用的结果(Tail2)。但是,由于某种原因,您编写了递归调用,其中也包含 A。我不太清楚你是怎么做到的,但你应该自己得到Tail2

      另外,你可以避免写Y==0,直接写在子句的头部。生成的代码如下所示:

      match([],[]).
      match([[A,0]|Tail], [A|Tail2]) :- match(Tail, Tail2), !.
      match([[_,_]|Tail], X) :- match(Tail, X).
      
      ?- match([[1,31],[2,0],[3,312],[4,0],[5,0]],X).
      X = [2, 4, 5]
      
      ?- match([[1,31],[2,0],[3,312],[4,312],[5,123]],X).
      X = [2]
      

      【讨论】:

      • 哇,非常感谢!我现在从序言开始,在逻辑编程中使用递归对我来说是新事物。有时很难理解我必须做什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 2019-03-13
      • 2021-11-05
      相关资源
      最近更新 更多