list - 如何比较序言中的两个列表,如果第二个列表由列表一的所有其他元素组成,则返回 true?

标签 list recursion prolog

我会通过比较第一个列表的第一个索引并向索引添加 2 来解决这个问题。但我不知道如何检查序言中的索引。 另外,我会创建一个计数器,当计数器为奇数时(如果我们从 0 开始计数),它会忽略列表中的内容。 你能帮助我吗? 例子: everyOther([1,2,3,4,5],[1,3,5]) 为 true,但 everyOther([1,2,3,4,5],[1,2,3]) 不是.

最佳答案

我们提供了三个逻辑上纯粹的定义,即使您只需要一个 - variatio delectat:)

  1. 两个相互递归谓词 list_oddies/2skipHead_oddies/2 :

    list_oddies([],[]).
    list_oddies([X|Xs],[X|Ys]) :-
       skipHead_oddies(Xs,Ys).
    
    skipHead_oddies([],[]).
    skipHead_oddies([_|Xs],Ys) :-
       list_oddies(Xs,Ys).
    
  2. 递归 list_oddies/2和非递归list_headless/2 :

    list_oddies([],[]).
    list_oddies([X|Xs0],[X|Ys]) :-
       list_headless(Xs0,Xs),
       list_oddies(Xs,Ys).
    
    list_headless([],[]).
    list_headless([_|Xs],Xs).
    
  3. 使用 的“一行” foldl/4Prolog lambdas 结合:

    :- use_module(library(lambda)).
    
    list_oddies(As,Bs) :-
       foldl(\X^(I-L)^(J-R)^(J is -I,( J < 0 -> L = [X|R] ; L = R )),As,1-Bs,_-[]).
    

所有三种实现都避免创建无用的选择点,但它们的做法不同:

  • #1 和 #2 使用第一个参数索引。
  • #3 使用 (->)/2(;)/2以逻辑上安全的方式——使用(<)/2作为条件。

让我们看一下 @WouterBeek 给出的查询 in his answer !

?- list_oddies([],[]),
   list_oddies([a],[a]),
   list_oddies([a,b],[a]),
   list_oddies([a,b,c],[a,c]),
   list_oddies([a,b,c,d],[a,c]),
   list_oddies([a,b,c,d,e],[a,c,e]),
   list_oddies([a,b,c,d,e,f],[a,c,e]),
   list_oddies([a,b,c,d,e,f,g],[a,c,e,g]),
   list_oddies([a,b,c,d,e,f,g,h],[a,c,e,g]).
true.                                           % all succeed deterministically

感谢 ,我们得到了逻辑上合理的答案——即使是最一般的查询:

?- list_oddies(Xs,Ys).
  Xs = [],                        Ys = []
; Xs = [_A],                      Ys = [_A]
; Xs = [_A,_B],                   Ys = [_A]
; Xs = [_A,_B,_C],                Ys = [_A,_C]
; Xs = [_A,_B,_C,_D],             Ys = [_A,_C]
; Xs = [_A,_B,_C,_D,_E],          Ys = [_A,_C,_E]
; Xs = [_A,_B,_C,_D,_E,_F],       Ys = [_A,_C,_E]
; Xs = [_A,_B,_C,_D,_E,_F,_G],    Ys = [_A,_C,_E,_G]
; Xs = [_A,_B,_C,_D,_E,_F,_G,_H], Ys = [_A,_C,_E,_G]
...

关于list - 如何比较序言中的两个列表,如果第二个列表由列表一的所有其他元素组成,则返回 true?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30036180/

相关文章:

python - 如何多次从带有关键字开始和结束的列表中获取子列表

python - 将数字和字符串列表转换为单个字符串 python

java - 如何根据状态打印列表项?

recursion - Lisp 排列函数——我在这里做错了什么?

prolog - 序一阶逻辑

scala - 从列表 Scala 中弹出最后一个元素

java - Spring boot + (JPA)-类别层次结构-递归遍历

java - 使用递归时 return 语句的混淆

list - 为什么在具体化中将 clpfd 变量分配给实际值?

Prolog:您能否根据值是否为基础值来使谓词表现不同?