用特定列表替换列表的每个元素

时间:2016-09-23 16:03:47

标签: list replace prolog

我尝试定义replaceEltByclass(E1:list,E2:list)E是没有子列表的列表。属于C类的E1的每个元素被替换为 C的元素。最终结果放在E2中。例如,目标rep_class([e1,e4,e6,e11],E2)将提供列表E2:[[e1,e8,e10],e4,[e3,e6,e7],e11]。我没有很好的结果。

/*The code*/
/*facts*/
class(c1,[e3, e6, e7]).
class(c2,[e1, e8, e10]).

/*rules*/

rep_class([],[]).

rep_class([E|Q],E2) :-
    class(C,L),
    not(member(E,L)),
    concat(E2,E,E2),
    rep_class(Q,E2).

rep_class([E|Q],E2) :-
    class(C,L),
    member(E,L),
    concat(E2,L,E2),
    rep_class(Q,E2).


/*conventional concat*/
concat([],L,L).
concat([H|T],L,[H|Res]) :- concat(T,L,Res).

1 个答案:

答案 0 :(得分:0)

问题在于:class(C,L),not(member(E,L)),,因为如果C = C2,它将给出两个解决方案,然后例如e1属于C2,因此当C = C1时它将用L和一个解决方案替换它它作为e1。你需要写“C存在这样的成员(e1,L)??”所以你必须收集所有可能的列表,看看成员(e1,L)是否代表一个列表L.所以如果有一些变化我的版本是:

class(c1,[e3, e6, e7]).
class(c2,[e1, e8, e10]).

rep_class([],[]).

rep_class([E|Q],[E|E2]) :-
    findall(L,class(_,L),List),
    not(find(List,E,_)),
    rep_class(Q,E2).

rep_class([E|Q],[Lout|E2]) :-
    findall(L,class(_,L),List),
    find(List,E,Lout),
    rep_class(Q,E2).

find([Lin|_],E,Lin):-member(E,Lin).
find([Lin|T],E,Lout):-not(member(E,Lin)),find(T,E,Lout).

举个例子:

?- rep_class([e1,e4,e6,e11], E2).
E2 = [[e1, e8, e10], e4, [e3, e6, e7], e11] ;
false.