Prolog 删除出现在子列表之后的给定列表的成员

Prolog 删除出现在子列表之后的给定列表的成员,prolog,Prolog,我试图删除Prolog中出现在子列表[z,z,z]后面的列表的所有成员。 f、 exremoveafterZZZ([a,b,c,z,z,a],X)->X=[a,b,c,z,z,z]。 我给出了子列表和连接的方法 % first argument is a sublist of the second argument sublist(Sublist, List):- join(_List1, List2, List), join(Sublist,_Lis

我试图删除Prolog中出现在子列表[z,z,z]后面的列表的所有成员。 f、 ex
removeafterZZZ([a,b,c,z,z,a],X)->X=[a,b,c,z,z,z]。

我给出了子列表连接的方法

    % first argument is a sublist of the second argument
    sublist(Sublist, List):-
       join(_List1, List2, List),
       join(Sublist,_List3, List2).


    % we get the list in third argument by joining lists from first two arguments
    join([], L, L).
    join([Head | Tail1], List2, [Head | Tail3]):-
    join(Tail1, List2, Tail3).
因此,我一直在考虑3种可能的输入“选项”:

1) []

2) 类似于[a,b,c],[a,b,c,z,z],其中输出自动为==输入

3) 类似于[a,b,c,z,z,z,a]

所以我想到了三条规则:

removeafterZZZ([],[]).   %for empty lists
removeafterZZZ(List,X) :=                   %for lists with no [z,z,z] sublist
       not ( sublist ( [z,z,z], List)) , 
       X = List.

removeafterZZZ([H|T], X) :=           %for lists with sublist [z,z,z]
       join(H, X, X),                 %join the head of list with X
       removeafterZZZ(T, X).          %call function again with tail

这显然不是这样的,我怎么知道我是否已经把z,z,z写进了输出列表?我应该用柜台吗?怎么做?

我认为你需要担心三种情况(三条规则…)

  • 空列表
    []
  • [z,z,z]开头的列表
  • 不以
    [z,z,z]开头的非空列表

  • 想一想如何用传统语言解决这个问题——你在列表中走到最后,或者在中间找到一个<代码> [z,z,z ] < /> >模式。

    如果允许使用AppEnter(它是用Prolog提供的标准列表谓词),这里有一个通用的方法来移除后缀-< /p> 它使用了一个cut,所以有点难看,但是如果你传入[](是的,是的,红色cut,随便什么),谓词2将给出一系列结果

    下面是它的工作原理,如果后缀不是列表的成员,选项2将激活,并且X和Z相等。否则它会说“存在两个列表,A和B可以构成我的原始列表。第二个列表,B,以我的后缀开始,然后包含所有内容(我不在乎这些内容是什么)。因为我知道A是后缀之前的所有内容,所以我的结果是A与Y连接。”

    请注意,这将为以下列表提供多个结果:

    [a,b,z,z,z,a,b,z,z,z]
    
    编辑以添加:如果您对返回以下结果的空列表满意,则可以删除第一行

    removeAfterSuff([a,b,c], [], Z).
    Z = []
    Z = [a]
    Z = [a,b]
    Z = [a,b,c]
    

    即使是家庭作业,也已经给出了完整的答复,所以

    remove_after([], _, []).
    remove_after([H|L], P, O) :-
            (   append(P, _, [H|L])
            ->  O = P
            ;   O = [H|O1],
                remove_after(L, P, O1) ).
    

    谢谢你的回答!因此,案例1)空列表:
    removafterzzz([],[])。%对于空列表
    我的规则正确吗?你只会得到一张空名单。对于其他情况。在传统语言中,每个z都有一个计数器I=0和+1,如果z=3,则忽略列表的其余部分。这将解决案例2)3),但如何在prolog中解决这个问题@那么你的密码就错了,我想。对于
    [z,a,z,z,x]
    它将返回
    [z,a,z,z]
    ,即使它不包含
    [z,z,z]
    。他可以使用append,除非他在OP中称之为
    join
    。啊,就是这样。我原以为join可能是秘密附加的,但没有仔细查看它以确定。非常感谢您的解释!这确实解决了我的问题。
    remove_after([], _, []).
    remove_after([H|L], P, O) :-
            (   append(P, _, [H|L])
            ->  O = P
            ;   O = [H|O1],
                remove_after(L, P, O1) ).