List 使用prolog将主列表分类为取代基

List 使用prolog将主列表分类为取代基,list,prolog,List,Prolog,我试图检查第一个列表中的任何元素是否与第二个列表中的元素匹配。如果找到匹配项,请将该元素分类并与该元素拆分,然后再次检查列表的其余部分。如果在特定分类中找到更多匹配项,则将这些列表追加 我尝试了下面的一些分类代码,但它没有正常工作。此格式的顺序仅适用于工作 ?- classify_substituens([1,2,ab,hj,de,as,t,pq,js,xy,ac],Ab,De,Pq,Xy,Rest). Ab = [1, 2, ab], De = [hj, de], Pq = [as, t, p

我试图检查第一个列表中的任何元素是否与第二个列表中的元素匹配。如果找到匹配项,请将该元素分类并与该元素拆分,然后再次检查列表的其余部分。如果在特定分类中找到更多匹配项,则将这些列表追加

我尝试了下面的一些分类代码,但它没有正常工作。此格式的顺序仅适用于工作

?- classify_substituens([1,2,ab,hj,de,as,t,pq,js,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = [hj, de],
Pq = [as, t, pq],
Xy = [js, xy],
Rest = [ac].
我的代码:

classify_ab(N,Ab,R):-append(B,[ab|R],N),append(B,ab,Ab),!.
classify_de(N,De,R):-append(B,[de|R],N),append(B,de,De),!.
classify_pq(N,Pq,R):-append(B,[pq|R],N),append(B,pq,Pq),!.
classify_xy(N,Xy,R):-append(B,[xy|R],N),append(B,xy,Xy),!.

classify_substituens(List,Ab,De,Pq,Xy,Rest):-
    classify_ab(List,Ab_1,Rest_1),
    classify_de(Rest_1,De_1,Rest_2),
    classify_pq(Rest_2,Pq_1,Rest_3),
    classify_xy(Rest_3,Xy_1,Rest4),
classify_substituens(Rest_4,Ab_2,De_2,Pq_2,Xy2,Rest),
    append(Ab_1,Ab_2,Ab),
    append(De_1,De_2,De),
    append(Pq_1,Pq_2,Pq),
    append(Xy_1,Xy_2,Xy),
    !.
classify_substituens(List,[],[],[],[],List).
我想要下面这样的目标

?- classify_substituens([1,2,ab,a,b,xy,as,t,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = [],
Pq = [],
Xy = [a,b,xy,as,t,xy],
Rest = [ac].
?- classify_substituens([1,2,ab,a,b,de,s,t,ab,i,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab,s,t,ab],
De = [a,b],
Pq = [],
Xy = [],
Rest = [i,ac].

为了简化我的生活,我把原子称为ab、de、pq和xy

您的代码恰好与此匹配,我认为这更简单:

takeUpto(Token, List, PrefixToken, Remainder) :-
    append(Prefix, [Token|Remainder], List),
    append(Prefix, [Token], PrefixToken).

classify_substituens(List, Ab, De, Pq, Xy, Rest) :-
    takeUpto(ab, List, Ab, R0),
    takeUpto(de, R0, De, R1),
    takeUpto(pq, R1, Pq, R2),
    takeUpto(xy, R2, Xy, Rest).
不幸的是,这仍然不起作用。你要做的就是把所有的东西都放进正确的箱子里。我看到了一种单传球的方法,但这相当糟糕。我花了大约30分钟在上面,发现调试起来太困难了。口头示意图是这样的:委托给一个助手方法,该方法带有累加器、一个“rest”变量和每个bin的两个变量:一个用于输入,一个用于输出。helper方法有一个获取空列表的例子;将输入变量映射到输出变量,将累加器映射到“rest”变量。现在,helper对每个“endcap”都有一个案例,它们看起来几乎一样:将累加器附加到endcap的singleton列表中,并将其作为该endcap的新状态变量转发到递归调用。这听起来很简单,但涉及11个变量和大量的复制/粘贴

不过,我确实想出了一个解决办法,在我看来,这个办法相当容易读写。这是没有效率的。对不起

首先,我想得到感兴趣的“取代基”。我把它们放在一起,然后用它们特有的味道给它们贴上标签

substituens(Acc, [], [], Acc).
substituens(Acc, [X|Xs], Subs, Rem) :-
    (   endcap(X) ->
        append(Acc, [X], Substituen),
        substituens([], Xs, RemainingSubs, Rem),
        append([X-Substituen], RemainingSubs, Subs)
    ;   append(Acc, [X], Acc1),
        substituens(Acc1, Xs, Subs, Rem)
    ).
这是这样的:

?- substituens([], [1,2,ab,a,b,de,s,t,ab,i,ac], Y, Rem).
Y = [ab-[1, 2, ab], de-[a, b, de], ab-[s, t, ab]],
Rem = [i, ac] ;
false.
我没有为这个做一个
substitunes/2
包装器,因为我只想从
classify\u substitunes/6
调用它。现在我说,假设我有一些endcap类别。让我从这个类似查找表的结构中获取所有内容

condense(Category, Groups, Condensed) :-
    findall(Group, member(Category-Group, Groups), MyGroups),
    append(MyGroups, Condensed).
这取决于
append/2
,它不是ISO,但可能不是很难编写,因为它只是
append/3
的固定点

这两个助手对取代基/6进行了简短的分类:

classify_substituens(List, Ab, De, Pq, Xy, Rest) :-
    substituens([], List, Subs, Rest),
    condense(ab, Subs, Ab),
    condense(de, Subs, De),
    condense(pq, Subs, Pq),
    condense(xy, Subs, Xy).
就在这里:

?- classify_substituens([1,2,ab,a,b,de,s,t,ab,i,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab, s, t, ab],
De = [a, b, de],
Pq = Xy, Xy = [],
Rest = [i, ac] ;
false.

?- classify_substituens([1,2,ab,a,b,xy,as,t,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = Pq, Pq = [],
Xy = [a, b, xy, as, t, xy],
Rest = [ac] ;
false.
顺便说一句,这也表明您的一个测试用例是错误的
De
必须始终以
De
结尾

我确实有一种挥之不去的感觉,那就是使用DCG或差异列表可能有一种高效且可读的方法来实现这一点,但我的DCG能力还不够强大,无法看到它。也许其他人会试试

所以,这是一个毫无意义的难题!这是很久以来我能回忆起的最奇怪的问题之一!我真的不明白你为什么会想要这个,但我希望我的代码能有所帮助,尽管它效率非常低

?- classify_substituens([1,2,ab,a,b,de,s,t,ab,i,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab, s, t, ab],
De = [a, b, de],
Pq = Xy, Xy = [],
Rest = [i, ac] ;
false.

?- classify_substituens([1,2,ab,a,b,xy,as,t,xy,ac],Ab,De,Pq,Xy,Rest).
Ab = [1, 2, ab],
De = Pq, Pq = [],
Xy = [a, b, xy, as, t, xy],
Rest = [ac] ;
false.