【问题标题】:prolog replace element in a list with another element, using a set function header?prolog 使用 set 函数头将列表中的元素替换为另一个元素?
【发布时间】:2015-08-17 19:49:44
【问题描述】:

我必须编写 tr 规则来将所有出现的列表元素值转换为另一个值。

tr(A,B,L,M) 如果列表 M 与列表 L 相同,只是 L 中出现的每个 A 都被 B 替换。例如:

?- tr(1,2,[1,4,1,5],L).
L = [2, 4, 2, 5].

到目前为止我所拥有的:

tr(_, _, [], []).
tr(O, R, [O|T], [R|T2]) :- tr(O, R, T, T2).
tr(O, R, [H|T], [H|T2]) :- H \= O, tr(O, R, T, T2).

有没有办法将tr(_, _, [], []). 替换为tr(A,B,L,M). 以便它使用字母A,B,L,M

【问题讨论】:

  • 你为什么要这样?规则tr(_,_,[],[]) 匹配空列表的大小写,这样一目了然。如果有 4 个不同的变量,你会得到什么?
  • 问问自己:“在空列表中哪个元素可以被另一个元素替换?”
  • tr(_, _, [], []). 是表达该特定规则的最合适的方式。你可以说,tr(A, B, L, M) :- L = [], M = [].,但它的效率略低,你会在AB 上收到单例变量警告。或者您可以说,tr(_A, _B, L, M) :- L = [], M = []. 以摆脱警告,但它仍然不如 tr(_, _, [], []). 清晰。

标签: list replace prolog


【解决方案1】:

我从@false 学到的这种模式。我目前正在学习,但也许您也可以将其中一些用于您的问题:

    tr(_,_,[],[]).
    tr(X,Y,[X|Xs],[Y|Rs]) :-
      tr(X,Y,Xs,Rs).
    tr(X,Y,[W|Ws],[W|Rs]) :-
      dif(X,W),
      tr(X,Y,Ws,Rs). 

例如:

    ?- tr(1,2,[1,4,1,5],L).
    L = [2, 4, 2, 5] ;
    false.

    ?- tr(A,B,[1,4,1,5],[2, 4, 2, 5]).
    A = 1,
    B = 2 ;
    false. 

【讨论】:

  • 很好,现在使用if_/3maplist/3 使其更紧凑!一条线,一个目标就够了!
  • 尝试并解释问题:?- tr(A,B,[C],[C]). 是什么意思?
【解决方案2】:

maplist 可以胜任:

tr(A, B, L, M) :-
    maplist(tr_one(A,B), L, M).

tr_one(A,B,A,B).
tr_one(A,_,B,B) :-
    A \= B.

答案与@guest 的查询相同。

【讨论】:

  • 请考虑使用dif/2 而不是(\=)/2。它有助于在使用非基础 Prolog 术语时保持逻辑合理性。
猜你喜欢
  • 2016-03-28
  • 1970-01-01
  • 2011-08-16
  • 2018-08-19
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
相关资源
最近更新 更多