【问题标题】:replacing list elements in sicstus prolog替换 sicstus prolog 中的列表元素
【发布时间】:2013-03-21 23:26:34
【问题描述】:

我正在编写一个 Prolog 谓词,它接受参数 (A1, A2, L1, L2),如果 L1 中所有出现的 A1 都已更改为 L2 中的 A2,则成功。

即:

| ?- replace(a, b, [a], X).
X = [b]

这是我写的:

replace(Orig,_,[Other],[Other]) :- Other \== Orig.
replace(Orig,Repl,[Orig],[Repl]).
replace(Orig,Repl,[Other|T1],[Other|T2]) :- Other \== Orig, replace(Orig,Repl,T1,T2).
replace(Orig,Repl,[Orig|T1],[Repl|T2]) :- replace(Orig,Repl,T1,T2).

现在,这可行,但似乎有点不雅。有没有更优雅的解决方案?

谢谢。

【问题讨论】:

    标签: list replace prolog prolog-dif


    【解决方案1】:

    SICStus Prolog 具有 dif/2,因此您可以像这样以纯粹的方式定义关系:

    replacement(A, B, X, Y) :-
       ( A = X, B = Y
       ; dif(A,X), X = Y
       ).
    
    maplist_replacement([], [], _, _).
    maplist_replacement([X|Xs], [Y|Ys], A, B) :-
       replacement(A, B, X, Y),
       maplist_replacement(Xs, Ys, A, B).
    
    | ?- maplist_replacement([1,2,3],Ys, 1,x)。 Ys = [x,2,3] ? ; 不 | ?- maplist_replacement([X,Y],[X,Y],A,B)。 B = A, X = A, Y = A ? ; B = A, X = A, 序言:dif__int(A,Y) ? ; B = A, Y = A, 序言:dif__int(A,X) ? ; 序言:dif__int(A,X), 序言:dif__int(A,Y) ? ; 不

    最后一个查询对应的问题是:AB 必须看起来像这样才能使两个元素列表保持不变?有四个答案:

    1. ABXY 都是一样的。

    2. ABX相同,Y不同。

    3. ABY相同,X不同。

    4. XY 都不同于 A

    在较新版本的 SICStus 中,maplist/3 位于库中,但定义并不完全单调。 有关maplist/3 的定义,请参阅Prolog map procedure that applies predicate to list elements

    【讨论】:

      【解决方案2】:

      怎么样:

      replace(A, B, X, Y) :- ( X == A -> Y = B ; Y = X ).
      

      例子:

      ?- maplist(replace(1,x), [1,2,3], Ls).
      Ls = [x, 2, 3].
      

      如果您愿意,很容易将 maplist/3 调用展开为递归谓词。

      【讨论】:

      • 不幸的是,maplist 不在 Sicstus 中。编辑:嗯,显然 Sicstus 应该有它,但不知何故我机器上的 Sicstus 没有。真可惜。 :)
      • 最近的版本肯定有。直接递归定义也很容易,只需要在上面的 replace/4 谓词中添加两行代码,并更改XY 来讨论列表而不是单个元素。
      猜你喜欢
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2016-03-28
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多