Prolog将列表中的特定字母复制到同一位置的另一个字母

时间:2016-05-15 14:05:29

标签: list prolog character

所以我试图在prolog中创建一个获取字符和2个列表的方法,无论在列表1中找到该字符的哪个位置,我都会在列表2中注入该字符。该方法返回新的状态清单2.即使我发现它是正确的,它似乎也不起作用。这是我的代码。

transfer([],[],_,[])
transfer([H¦T],[_¦T1],C,R):-
    transfer(T,T1,C,R1),
    H==C,
    append([H],R1,R).

所以,如果我执行? - 转移([h,e,l,l,o],[0,0,0,0,0],e,X)。我得到结果X = [0,e,0,0,0]。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

想一想你的谓词应该描述什么样的关系。如果前两个列表为空,则无论比较元素如何,最后一个参数也是空列表。这是您已有的基本情况。否则你有两个互斥的案例:

  1. 第一个列表的头部等于比较元素。在这种情况下,比较元素位于结果列表中。

  2. 第一个列表的头部与比较元素不同。在这种情况下,第二个列表的头部位于结果列表中。

  3. 您可以使用or-predicate ;对此案例区分进行建模。转移/ 4可能看起来像这样:

    transfer([],[],_,[]).
    transfer([H1|T1],[H2|T2],C,[R|Rs]):-
       ((H1=C,R=C);(dif(H1,C),R=H2)),     % case 1 or case 2
       transfer(T1,T2,C,Rs).              % the relation holds for the tails as well
    

    使用此定义,您的示例查询会产生所需的结果:

       ?- transfer([h,e,l,l,o],[0,0,0,0,0],e,X).
    X = [0,e,0,0,0] ? ;
    no
    

    或者你也可以在一个单独的谓词中描述上面的案例区别,然后使用maplist / 4将关系应用于三个列表:

    :- use_module(library(apply)).
    
    e_x_y_z(E,X,Y,Z) :-
       (X=E,Z=E);(dif(X,E),Z=Y).
    
    transfer(L1,L2,C,R) :-
       maplist(e_x_y_z(C),L1,L2,R).
    

    我发现这个版本更容易阅读,因为实际关系的定义与递归分开。注意e_x_y_z / 4中的比较元素是第一个参数,因此谓词可以传递给maplist / 4,它们分别缺少三个参数的三个参数。