Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 查找Prolog列表元素的组合/子列表_List_Prolog - Fatal编程技术网

List 查找Prolog列表元素的组合/子列表

List 查找Prolog列表元素的组合/子列表,list,prolog,List,Prolog,我正在尝试编写一个函数,该函数将通过删除1或2个元素(包括拆分列表)来生成列表元素的组合 例如: [b,b,b] 可能成为 [b,b] [b] [[b],[b]] 我可以使用以下谓词生成前两个谓词: permute([_|T],T). permute([_|[_|T]],T). 但事实证明,第三个问题更加困难。我可以使用append将列表分成两部分,但我不知道如何将其与我已有的内容结合起来 我正在使用SWI Prolog (虽然被标记为家庭作业,但这是一个更大作业的一部分,也是我目前所处的

我正在尝试编写一个函数,该函数将通过删除1或2个元素(包括拆分列表)来生成列表元素的组合

例如:

[b,b,b]
可能成为

[b,b]
[b]
[[b],[b]]
我可以使用以下谓词生成前两个谓词:

permute([_|T],T).
permute([_|[_|T]],T).
但事实证明,第三个问题更加困难。我可以使用
append
将列表分成两部分,但我不知道如何将其与我已有的内容结合起来

我正在使用SWI Prolog

(虽然被标记为家庭作业,但这是一个更大作业的一部分,也是我目前所处的困境)

谓词

permute([_|T],T).
permute([_|[_|T]],T).
将更恰当地命名为
tail\u或\u tail的\u tail\u
。您是否注意到它只能删除第一个或前两个元素?如果您想去掉任意两个元素,请使用

take_out_one_or_two(L, R) :- select(_, L, R).
take_out_one_or_two(L, R) :- select(_, L, L1), select(_, L1, R).
您是对的,拆分可以通过
append/3
完成。你(相当奇怪)的要求得到了满足

strange_predicate(L, R) :- take_out_one_or_two(L, R).
strange_predicate(L, [X,Y]) :- take_out_one_or_two(L, L1), append(X, Y, L1).
如果不希望结果中出现空列表,请将第二个子句替换为

strange_predicate(L, [X,Y]) :-
    take_out_one_or_two(L, L1),
    X = [_|_],
    Y = [_|_],
    append(X, Y, L1).

(如果没有用例,我真的想不出这个谓词的名称。)

以Kayles的游戏为例,我们的应用表明一个经济的状态表示应该是一个正整数的有序列表,每个数字代表一个连续的瓶子串

我之所以说有序,是因为在这些值的任何排列下,游戏的状态都是等价的

因此,可能的行动包括选择一个条目,并将其减少一个或两个,变成零,一个或两个较小的条目。这些较小的条目(如果有的话)应该被插入到游戏状态列表的新“尾部”的适当位置

游戏动作更大的表现形式的一个组成部分是决定一个连续的X瓶串可以减少多少种方式。因此,我们可以从这一要求开始:

bowls(X,[ ]) :-
    ( 0 is X - 1 ; 0 is X-2 ).
bowls(X,[W]) :-
    ( W is X - 1 ; W is X-2 ),
    W > 0.
bowls(X,[Y,Z]) :-
    ( W is X - 1 ; W is X-2 ),
    W > 1,
    bowlsplits(W,Y,Z).
读者可以使用
Y>=Z>0产生
Y+Z=W
的所有可能性来实现bowlsplits/3

请注意,使用这种表示法时,我们应该跳过与列表中的下一个条目相等的任何条目,以避免重复结果,因为两个相等的条目产生相同的可能结果

kayles([X],R) :- bowls(X,R).
kayles([X,Y|T],R) :-
    X > Y,
    bowls(X,L),
    inSort(L,[Y|T],R).
kayles([X,X|T],[X|L]) :-
    kayles([X|T],L).
读者还可以按照插入排序的方式在rt/3中实现,插入排序将前两个参数中的有序列表合并到一个有序列表中,以绑定第三个参数


请注意,kayles/2是尾部递归但不确定的。

这些不是排列,所以请不要这样称呼它们。它们有正确的术语吗?(变体/子列表?)!这是针对Kayles的游戏,列表元素表示可以一组或两组打翻的瓶子,因此出现了奇怪的要求,一组可以分成两半。由于所有元素都是相同的,从开始或结束删除元素没有什么区别,但是感谢更新的谓词。@dig412:如果所有元素都是相同的,那么您就不需要列表了。一个整数计数器或一对
Elem+Count
(例如
b+3
)就足够了。这可以工作,它肯定会简化一些列表操作。我仍然习惯于Prolog,这是一种非常不同的编程方式。