如何检查列表是否是Prolog中另一个列表的非空子列表

时间:2015-01-26 17:10:16

标签: prolog sublist

我正在尝试创建一个included_list(X,Y)术语,用于检查X是否为Y的非空子列表。

我已经用它来检查Y列表中是否存在元素

check_x(X,[X|Tail]).
check_x(X,[Head|Tail]):- check_x(X,Tail).

附加条款

append([], L, L).
append([X | L1], L2, [X | L3]) :- append(L1, L2, L3).

创建一个列表,以便程序完成

included_list([HeadX|TailX],[HeadX|TailX]).

但我在处理我想通过"追加"创建的新空列表时遇到问题。 (我想创建一个空列表来添加确认存在于两个列表中的元素。)

我找到了这个

sublist1( [], _ ).
sublist1( [X|XS], [X|XSS] ) :- sublist1( XS, XSS ).
sublist1( [X|XS], [_|XSS] ) :- sublist1( [X|XS], XSS ).

但在子列表([],[1,2,3,4)

上变为真

5 个答案:

答案 0 :(得分:3)

由于您正在寻找非连续子列表有序子集,并且不想包含空列表,因此:

sub_list([X], [X|_]).
sub_list([X], [Y|T]) :-
    X \== Y,
    sub_list([X], T).
sub_list([X,Y|T1], [X|T2]) :-
    sub_list([Y|T1], T2).
sub_list([X,Y|T1], [Z|T2]) :-
    X \== Z,
    sub_list([X,Y|T1], T2).

一些结果:

| ?- sub_list([1,4], [1,2,3,4]).

true ? a

no
| ?- sub_list(X, [1,2,3]).

X = [1] ? a

X = [2]

X = [3]

X = [1,2]

X = [1,3]

X = [1,2,3]

X = [2,3]

(2 ms) no
| ?- sub_list([1,X], [1,2,3,4]).

X = 2 ? a

X = 3

X = 4

(2 ms) no

请注意,它不只是告诉您一个列表是否是另一个列表的子列表,但它会回答更常见的问题,例如 L的哪些子列表?在谓词中使用剪切时,它可以删除可能的有效解决方案。因此,这个解决方案避免了使用切割。

说明:

这个想法是生成一组规则,这些规则定义子列表是什么,并尝试这样做而不是程序或命令。以上条款可以解释为:

  1. [X]是列表[X|_]
  2. 的子列表 如果[X][Y|T]不同且X是列表Y的子列表,则
  3. [X]是列表T的子列表。 XY不同的条件会阻止此规则与规则#1重叠,并通过避免不必要的递归来大大减少执行查询所需的推断数。
  4. 如果[X,Y|T1][X|T2]的子列表,则
  5. [Y|T1]T2的子列表。表单[X,Y|T1]确保列表至少包含两个元素,以免与规则#1重叠(这可能导致任何单个解决方案重复多次)。
  6. 如果[X,Y|T1][Z|T2]不同且XZ的子列表,则
  7. [X,Y|T1]T2的子列表。表单[X,Y|T1]确保列表至少包含两个元素,以免与规则#2重叠,XZ条件不同会阻止此规则与规则#重叠3(可以导致任何单个解决方案重复多次),并通过避免不必要的递归大大减少执行查询所需的推断次数。

答案 1 :(得分:1)

这是你要做的事情:

mysublist(L,L1):- sublist(L,L1), notnull(L).

notnull(X):-X\=[].

sublist( [], _ ).
sublist( [X|XS], [X|XSS] ) :- sublist( XS, XSS ).
sublist( [X|XS], [_|XSS] ) :- sublist( [X|XS], XSS ).

参考: Prolog - first list is sublist of second list? 我刚刚添加条件以检查它是否为空。

希望这有帮助。

答案 2 :(得分:1)

我会使用追加:

sublist(X, []) :-
    is_list(X).


sublist(L, [X | Rest]) :-
    append(_, [X|T], L),
    sublist(T, Rest).

答案 3 :(得分:0)

如果订单很重要。示例[1,2,3][1,2,3,4]的子列表,但[1,3,2]不是。

你可以这样做。

sublist([],L).
sublist([X|L1],[X|L2]):- sublist(L1,L2)

答案 4 :(得分:0)

基本上我们可以检查M是否是L的子列表,如果M存在于L中,则在其背面和/或其前面附加一些东西。

append([], Y, Y).
append([X|XS],YS,[X|Res]) :- append(XS, YS, Res).

sublist(_, []).
sublist(L, M) :- append(R, _, L), append(_, M, R).