list 列表替换中的 Prolog 元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5850937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prolog element in lists replacement
提问by Donald
Hi i was wondering if you could help me out with this
嗨,我想知道你能不能帮我解决这个问题
From programming in Prolog: write Prolog script for replacement any given element in lists by an another given element. For example:
从 Prolog 编程:编写 Prolog 脚本,用另一个给定元素替换列表中的任何给定元素。例如:
replace( 3, a,[1,2,3,4,3,5], [1,2,a,4,a,5])=true
Many Thanks in advance
提前谢谢了
回答by svick
In Prolog, most list processing is done by processing the head and then recursively processing the rest of the list. Of course, you can't forget about the base case, which is an empty list.
在 Prolog 中,大多数列表处理是通过处理头部然后递归处理列表的其余部分来完成的。当然,您不能忘记基本情况,它是一个空列表。
Replacing anything with anything in an empty list results again in an empty list. If the head of the list is the same as the element to replace, replace it, otherwise, keep it as it is. In both cases, process recursively the rest of the list. Translated from English into Prolog:
用空列表中的任何内容替换任何内容再次导致空列表。如果链表的头部与要替换的元素相同,则替换它,否则,保持原样。在这两种情况下,递归处理列表的其余部分。从英文翻译成Prolog:
replace(_, _, [], []).
replace(O, R, [O|T], [R|T2]) :- replace(O, R, T, T2).
replace(O, R, [H|T], [H|T2]) :- H \= O, replace(O, R, T, T2).
回答by repeat
Allimplementations presented so far in other answers are logically unsoundwhen being used with non-ground terms. Consider the original query and a slight variant:
到目前为止,其他答案中提出的所有实现在与非基础术语一起使用时在逻辑上都是不合理的。考虑原始查询和一个轻微的变体:
?- replace(3,three,[1,2,3],Xs).
Xs = [1,2,three] ; % OK: correct
false
?- A=3, replace(A,B,[1,2,3],Xs). % OK: correct
Xs = [1,2,B], A = 3 ;
false
It works! Let's ask some very similar queries:
有用!让我们问一些非常相似的查询:
?- replace(A,B,[1,2,3],Xs). % FAIL: should succeed more than once...
Xs = [B,2,3], A = 1 ; % ... but the other solutions are missing
false
?- replace(A,B,[1,2,3],Xs), A=3. % FAIL: this query _should_ succeed ...
false % ... it does not!
What's going on?Put the blameon meta-logical builtins(!)/0
and (\=)/2
, which are very hard to use rightand often make code brittle, impure, and logically unsound.
这是怎么回事?把怪的元逻辑内建(!)/0
和(\=)/2
,这是非常困难的使用权,并经常使代码脆,不纯,并且在逻辑上站不住脚。
To preserve logical soundness, stick to logical purityand abstain from meta-logical "features" whenever possible! Luckily, most Prolog implementations support dif/2
as a logical alternative to (\=)/2
. Let's use it:
为了保持逻辑的健全性,尽可能坚持逻辑纯洁性,避免元逻辑“特征”!幸运的是,大多数 Prolog 实现都支持dif/2
作为(\=)/2
. 让我们使用它:
% code by @svick, modified to use dif/2 instead of (\=)/2
replaceP(_, _, [], []).
replaceP(O, R, [O|T], [R|T2]) :- replaceP(O, R, T, T2).
replaceP(O, R, [H|T], [H|T2]) :- dif(H,O), replaceP(O, R, T, T2).
Let's run above queries again, this time with the improved replaceP/4
:
让我们再次运行上面的查询,这次使用改进的replaceP/4
:
?- replaceP(3,three,[1,2,3],Xs).
Xs = [1,2,three] ; % OK: correct, like before
false
?- replaceP(A,B,[1,2,3],Xs). % OK: four solutions, not just one
Xs = [B,2,3], A = 1 ;
Xs = [1,B,3], A = 2 ;
Xs = [1,2,B], A = 3 ;
Xs = [1,2,3], dif(A,1),dif(A,2),dif(A,3) ;
false
?- replaceP(A,B,[1,2,3],Xs), A=3. % OK (succeeds now)
Xs = [1,2,B], A = 3 ;
false
?- A=3, replaceP(A,B,[1,2,3],Xs). % OK (same as before)
Xs = [1,2,B], A = 3 ;
false
回答by Davorin Ru?evljan
replace(_, _ , [], []).
replace(X, Y, [ X | Z ], [ Y | ZZ]):- ! , replace( X, Y, Z, ZZ).
replace(X, Y, [ W | Z], [ W | ZZ] :- replace(X, Y, Z, ZZ).
Though, one would usually arrange the 3. arg to be the first one. And strictly speaking above does not replace anything in the list, it just anwsers if 4th arg is like the one in the 3rd but with Y' instead of X'.
但是,通常会将 3. arg 安排为第一个。严格来说,上面没有替换列表中的任何内容,如果第 4 个参数类似于第 3 个参数,但使用 Y' 而不是 X',它只是回答。
回答by bearzk
replace(E,S,[],[]).
replace(E,S,[E|T1],[S|T2]):-replace(E,S,T1,T2).
replace(E,S,[H|T1],[H|T2]):-E\=H, replace(E,S,T1,T2).
the idea is simple, if the elements match, change it, if not, go forward until empty.
这个想法很简单,如果元素匹配,则更改它,如果不匹配,则继续直到为空。
回答by Maik
domains
I=integer*
K=integer*
Z=integer
A=integer
predicates
nondeterm rep(I,Z,A,K)
clauses
rep([],_,_,[]).
rep([Z|T1],Z,A,[A|T2]):- rep(T1,Z,A,T2).
rep([H|T1],Z,A,[H|T2]) :- rep(T1,Z,A,T2).
goal
rep([1,2,3],2,4,X).