【发布时间】:2021-03-16 14:35:26
【问题描述】:
我是 Prolog 的新手,我一直坚持写这个谓词。基本上给了我一个列表,我需要找到最常见的 N 大小的子列表。示例:
-
most_common_sublist([1,2,2,3,2,2,4,2,2,3],1,L),输出应该是L=[2]; -
most_common_sublist([1,2,2,3,2,2,4,2,2,3],2,L),输出应该是L=[2,2]; -
most_common_sublist([1,2,2,3,2,2,4,2,2,3],3,L),输出应该是L=[2,2,3];
我的方法是编写一个谓词来获取列表的前 N 个元素,编写第二个谓词,它就像一个生成器(一遍又一遍地调用第一个谓词,直到列表缩短到大小为 N),然后检查所有生成的子列表有多少次匹配并获得最大值。
我被生成器谓词卡住了,其余的我很确定我知道怎么写。
这是我目前的代码:
length([],0).
length([_|L],N) :- N is M+1, length(L,M).
// This will get the first N elements from the list.
// I tested it and it works.
sublist([H|_],1,[H]).
sublist([H|T],N,[H|LOP]) :- M is N-1, sublist(T,M,LOP).
// This is supposed to generate all the sublists,
// length is a predicate that returns the length of the list.
generator(L,N,L) :- length(L,M), N=:=M.
generator([H|T],N,[PN|LOP]) :- sublist([H|T],N,PN), generator(T,N,LOP).
这是我得到的错误:
?- generator([1,2,3,4,5,6,7],2,X).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [12] _6018 is _6024+1
ERROR: [11] length([1,2|...],_6052) at c:/users/ace_m/documents/prolog/bp.pl:44
ERROR: [10] generator([1,2|...],2,[1,2|...]) at c:/users/ace_m/documents/prolog/bp.pl:83
ERROR: [9] <user>
Exception: (10) generator([1, 2, 3, 4, 5, 6, 7], 2, _5204) ?
我知道错误意味着我没有传递正确的值,但我不明白我哪里出错了。任何帮助
【问题讨论】:
-
您的错误是指使用
+的表达式,但您发布的代码都没有。 -
@ScottHunter 我猜这是来自长度谓词,我也把它放在我的代码中。
-
1) 为什么不使用内置的
length/2而不是使用自己的? 2) 子列表编写正确,但您可以更轻松地编写:sublist(L,N,SL) :- length(SL,N), append(SL,_,L)3) 在生成器/3 的第一个子句中,M 在调用 length/2 时未实例化,因此计算 N 为 M+1 将失败 -
4) 你会使用表格吗?因为这听起来像是……mode-directed tabling 的案例(嘿,是时候使用除 Prolog 90 年代的老歌之外的其他功能了)
-
@DavidTonhofer 我不应该使用内置谓词,我应该自己编写它们……我想这是最好的,因为这是学习东西,谢谢你的回复,虽然我解决了我的问题!
标签: list recursion prolog instantiation-error