Prolog - 第一个列表是第二个列表的子列表?
例如:
isin([1,2,3], [1,0,1,2,3,0])
将产生 true,因为 123
位于 101230
我编写了以下代码:
isin([AH|AT],[AH|AT]).
isin([AH|AT],[BH|BT]):- AH = BH, isin(AT,BT), isin([AH|AT],BT).
似乎不起作用。尽量不要使用任何内置函数,顺便说一句,Prolog 有一个内置的 sublist(L1, L2)
函数。
如何使用 SWI-Prolog 编写针对内置函数的查询?我尝试直接编写:
?- sublist([1],[2]).
但它返回一个未定义的过程
错误。
另外,是否可以查看内置函数的编码方式以及如何编码?
For example:
isin([1,2,3], [1,0,1,2,3,0])
will yield true because 123
is inside of 101230
I wrote the following code:
isin([AH|AT],[AH|AT]).
isin([AH|AT],[BH|BT]):- AH = BH, isin(AT,BT), isin([AH|AT],BT).
seems not working. Try not to use any built-in functions and BTW, Prolog has a built-in sublist(L1, L2)
function.
How do I write a query against a built-in function using SWI-Prolog ? I tried to directly write:
?- sublist([1],[2]).
but it returns an undefined procedure
error.
Also, is it possible to see how a built-in function is coded and how ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果您想
...成功,但
...失败,您可能需要考虑
注意,如果您将变量作为子列表传递,回溯将为您提供 List 的所有可能子列表的全面集合,但这将在一般包括空列表的多次重复(因为空列表可以在追加操作中与它们前面和后面的所有其他子列表组合)。
If you want
...to succeed, but
...to fail, you might want to consider
Note that if you pass a variable through as Sublist, backtracking will give you a comprehensive set of all possible sublists of List, but this will in general include several repeats of the empty list (because the empty list can combine with all other sublists both ahead and behind of them in an append operation).
因为这似乎是家庭作业,所以我只会给您一些提示:
您似乎错过了空列表是另一个列表的子列表的情况。
您将“子列表从这里开始”和“子列表稍后开始”这两种情况混合到一个子句中。
您
看来子列表的元素在较大列表中应该是连续的。为此,您需要两个谓词。本质上,您必须记住,当您拆开列表时,子列表已经开始。
没有内置的
sublist/2
,只有一个sublist/3
可以做不同的事情(带有谓词的过滤列表)。Since it seems to be homework I will only give you a few hints:
It seems you are missing the case where an empty list is a sublist of the other one.
You mixed the two cases "the sublist starts here" and "the sublist starts later" into one clause.
It seems the elements of the sublist should be consecutive in the larger list. For that you need two predicates. Essentially you have to remember that the sublist has started when you take apart the lists.
There is no builtin
sublist/2
, only asublist/3
which does something different (filter list with a predicate).使用 member 的另一个实现是:
如果在列表中找到该元素,member/2 返回 true
another implementation using member is :
member/2 returns true if find the element in a list
为了避免失败情况下的堆栈溢出,我们必须确定列表
P
的大小。to avoid stack overflow for failing cases we must determine the size of the list
P
.如果您尝试这些查询:
If you try these queries:
通过对 ДМИТРИЙ МАЛИКОВ 的答案进行一些修改,这是有效的,
本质上,寻找子的第一个元素之间的匹配-list 和使用
subList
过程的主列表。当发生匹配时,转到preList
过程并检查这是否是列表其余部分的前缀。如果是这样,决议就成功了。如果没有,请返回并继续比较列表的其余部分以查找第一个元素匹配。
With a few modifications to ДМИТРИЙ МАЛИКОВ's answer, this is something that works,
Essentially, look for a match between the first elements of the sub-list and the main-list using the
subList
procedure. When a match occurs, head over to thepreList
procedure and check if this turns out to be a prefix for the remainder of the list. If so, the resolution ends in success.If not, come back and continue comparing the remainder of the list for a first-element match.