我想生成一个谓词,它能够检查列表是否会分成每个包含至少三个原子的子列表。
例如:
findgroups([1,2,3,4,5,6,7,8,9],L1).
有解决方案如:
L1=[[1,2,3],[4,5,6],[7,8,9]]
L1=[[1,2,3,4],[5,6,7,8,9]]
L1=[[1,2,3,4,5],[6,7,8,9]]
L1=[[1,2,3,4,5,6],[7,8,9]]
但是,以下内容将失败:
findgroups([1,2,3,4,5]).
我已经编写了一些基于使用append将列表拆分为两个子术语的谓词,但我对处理多个子列表感到困惑。
非常感谢您的帮助
祝福 Ĵ
答案 0 :(得分:5)
让我们从一个好名字开始吧! findgroups/2
这意味着你想要命令Prolog:Prolog确实找到了我的一些团体!快点!这真的很合适吗?我们来看看:
?- findgroups(L, [[1,2,3],[4,5,6],[7,8,9]]).
谁在这里找到任何一个团体?它们已经存在!所以你的名字真的是用词不当。相反,通过描述每个参数来撰写名称。第一个参数是关于列表,第二个是关于列表的列表。所以:
?- list_lists(L, [[1,2,3],[4,5,6],[7,8,9]]).
更好,但有点过于笼统。也许:
?- elements_trigroups(L, [[1,2,3],[4,5,6],[7,8,9]]).
所以查询现在读取:这里是所有的三元组,相应的元素是什么?元素是一个冗长的词,els也很好。
我的第一次(有点过于笼统)尝试:
es_trigroups(Es, Ess) :-
phrase(seqq(Ess), Es).
请注意变量名称:Es
:E
的列表。 Ess
是Es
的列表,而E
依次是seqq//1
的列表。
使用another answer中定义的?- es_trigroups([1,2,3,4,5], [Es,Fs]).
Es = [], Fs = [1,2,3,4,5]
; Es = [1], Fs = [2,3,4,5]
; ...
。
Darn,它仍然成功:
es_trigroups(Es, Ess) :-
trigroups(Ess),
phrase(seqq(Ess), Es).
trigroups([]).
trigroups([Es|Ess]) :-
Es = [_,_,_|_],
trigroups(Ess).
但它并没有那么糟糕,因为它成功地满足了你所要求的所有情况。简介:这种关系太笼统了。我们需要专门化它。
专门化关系的一种简单方法是添加更多目标,例如:
es_trigroups_bis(Es, Ess) :-
phrase(seqq(Ess), Es),
trigroups(Ess).
所以现在一切似乎都很好。只有一件事,那不是很好:termination property可能会更好。有时我们需要交换目标。
B
结果终止条件为:
es_trigroups(A,B)terminates_if b(B). % optimal. loops found: [es_trigroups(_,[[_,_,_|_]|_]),es_trigroups(y,[[_,_,_|_]|_])]. NTI took 0ms,74i,74i es_trigroups_bis(A,B)terminates_if b(B). % optimal. loops found: [es_trigroups_bis(_,[[]|_]),es_trigroups_bis(y,[[]|_])]. NTI took 0ms,79i,79i
但我们真正想要的是,终止条件不仅取决于A
(第二个参数),还取决于A
。也就是说,B
或es_trigroups_ter(Es, Ess) :-
phrase(seq3s(Ess), Es).
seq3s([]) --> [].
seq3s([Es|Ess]) --> {Es = [_,_,_|_]}, seq(Es), seq3s(Ess).
单独可以保证终止。为此,我们必须交织两种定义:
SessionManager
现在,终止条件为excellent!
es_trigroups_ter(A,B)terminates_if b(A);b(B). % optimal. loops found: [es_trigroups_ter([A|_],[[A,_,_|_]|_])]. NTI took 0ms,77i,77i
答案 1 :(得分:0)
也许这个非常简单的解决方案可以做到
findgroups([], []).
findgroups(L, [[A,B,C|D]|Gs]) :-
append([A,B,C|D], R, L),
findgroups(R, Gs).
不要求最后一个解决方案,但这是正确的,因为您不排除只有一个元素的组
?- findgroups([1,2,3,4,5,6,7,8,9], Gs).
Gs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] ;
Gs = [[1, 2, 3], [4, 5, 6, 7, 8, 9]] ;
Gs = [[1, 2, 3, 4], [5, 6, 7, 8, 9]] ;
Gs = [[1, 2, 3, 4, 5], [6, 7, 8, 9]] ;
Gs = [[1, 2, 3, 4, 5, 6], [7, 8, 9]] ;
Gs = [[1, 2, 3, 4, 5, 6, 7, 8|...]] ;
false.
为了完全匹配这些例子,我会写
findgroups(L, Gs) :- findgroups_(L, Gs), Gs = [_,_|_].
findgroups_([], []).
findgroups_(L, [[A,B,C|D]|Gs]) :-
append([A,B,C|D], R, L),
findgroups_(R, Gs).