如何更改列表中两个元素的位置(PROLOG)

如何更改列表中两个元素的位置(PROLOG),prolog,Prolog,谓词改变位置(E1、E2、Lin、Lout)。 Lin有任意数量的元素,我需要将所有出现的E1更改为E2,反之亦然。然后返回Lout 我在想这样做: change(X, Y, [], []). change(X, Y, [X|L], [Y,L1]):- change(X,Y,L,L1). change(X, Y, [Z|L], [Z,L1]:- X \== Z, change(X,Y,L,L1). 但这种方式并不是刷两个号码的列表你就快到了。您的基本情况(空列表)和第二条规则(将X交换为Y)基

谓词
改变位置(E1、E2、Lin、Lout)。

Lin
有任意数量的元素,我需要将所有出现的
E1
更改为
E2
,反之亦然。然后返回
Lout


我在想这样做:

change(X, Y, [], []).
change(X, Y, [X|L], [Y,L1]):- change(X,Y,L,L1).
change(X, Y, [Z|L], [Z,L1]:- X \== Z, change(X,Y,L,L1).

但这种方式并不是刷两个号码的列表

你就快到了。您的基本情况(空列表)和第二条规则(将
X
交换为
Y
)基本上没有问题(除了注释中指出的细节)。但是,您缺少一条反之亦然的规则(将
Y
交换为
X
)。在上一条规则中,您可能希望确保
Z
不仅与
X
不同,而且与
Y
不同,否则
Z
将受规则二或三的约束

change(X, Y, [], []).
change(X, Y, [X|L], [Y|L1]) :-
   change(X,Y,L,L1).
change(X, Y, [Y|L], [X|L1]) :-   % <- vice versa case
   change(X,Y,L,L1).
change(X, Y, [Z|L], [Z|L1]) :-
      dif(X,Z),                  % <- neither X=Z
      dif(Y,Z),                  % <- nor vice versa
      change(X,Y,L,L1).
[2,1,3,4]
2
交换
1
之前是什么样子的,反之亦然

如果生成的列表是
[2,1,3,4]
,则在
[1,2,3,4]
中交换了哪些元素


你快到了。您的基本情况(空列表)和第二条规则(将
X
交换为
Y
)基本上没有问题(除了注释中指出的细节)。但是,您缺少一条反之亦然的规则(将
Y
交换为
X
)。在上一条规则中,您可能希望确保
Z
不仅与
X
不同,而且与
Y
不同,否则
Z
将受规则二或三的约束

change(X, Y, [], []).
change(X, Y, [X|L], [Y|L1]) :-
   change(X,Y,L,L1).
change(X, Y, [Y|L], [X|L1]) :-   % <- vice versa case
   change(X,Y,L,L1).
change(X, Y, [Z|L], [Z|L1]) :-
      dif(X,Z),                  % <- neither X=Z
      dif(Y,Z),                  % <- nor vice versa
      change(X,Y,L,L1).
[2,1,3,4]
2
交换
1
之前是什么样子的,反之亦然

如果生成的列表是
[2,1,3,4]
,则在
[1,2,3,4]
中交换了哪些元素


我假设,因为这是家庭作业,所以这是一个学习列表处理和递归的练习。但在Prolog中,在列表中依次处理每个术语的常用工具是
maplist

% Rule for changing one element
change_element(X, Y, X, Y).
change_element(X, Y, Y, X).
change_element(X, Y, Z, Z) :- dif(X, Z), dif(Y, Z).

% Rule for changing a list
change(X, Y, L1, L2) :-
    maplist(change_element(X, Y), L1, L2).
这将产生:

?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b] ? ;

no
?-
?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b].

?-

对于测定溶液,您可以使用:

这将产生:

?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b] ? ;

no
?-
?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b].

?-

我假设,因为这是家庭作业,所以这是一个学习列表处理和递归的练习。但在Prolog中,在列表中依次处理每个术语的常用工具是
maplist

% Rule for changing one element
change_element(X, Y, X, Y).
change_element(X, Y, Y, X).
change_element(X, Y, Z, Z) :- dif(X, Z), dif(Y, Z).

% Rule for changing a list
change(X, Y, L1, L2) :-
    maplist(change_element(X, Y), L1, L2).
这将产生:

?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b] ? ;

no
?-
?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b].

?-

对于测定溶液,您可以使用:

这将产生:

?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b] ? ;

no
?-
?- change(a, b, [a,b,c,b,a], L).

L = [b, a, c, a, b].

?-


我在考虑做这样的事情:改变(X,Y,[],[])。改变(X,Y,[X | L],[Y,L1]):-改变(X,Y,L,L1)。change(X,Y,[Z | L],[Z,L1]:-X\==Z,change(X,Y,L,L1)。但这种方式并不是刷两个数字list@JessicaSimoes-尝试将
[Y,L1]
更改为
[Y | L1]
[Z,L1]
更改为
[Z | L1]
。你真的很接近了!你还缺少了一个
在第三句的
:-
前面。@Enigmativity噢,我明白了。您将OP的注释代码复制到问题中。我通常试着让他们做这件事。:)但是,考虑到这些代码,我不认为关闭是有依据的。@false-我投票赞成重新打开。我想做一些类似的事情:更改(X,Y,[],[])。改变(X,Y,[X | L],[Y,L1]):-改变(X,Y,L,L1)。change(X,Y,[Z | L],[Z,L1]:-X\==Z,change(X,Y,L,L1)。但这种方式并不是刷两个数字list@JessicaSimoes-尝试将
[Y,L1]
更改为
[Y | L1]
[Z,L1]
更改为
[Z | L1]
。你真的很接近了!你还缺少了一个
在第三句的
:-
前面。@Enigmativity噢,我明白了。您将OP的注释代码复制到问题中。我通常试着让他们做这件事。:)但是,考虑到这些代码,我不认为关闭是有依据的。@false-我投票赞成重新打开。所有这些
;否
。。。那么
change(a,a,[a],[a])
的两(2)个冗余答案呢?@false:有趣的事实:在Yap中,查询
?-change(a,a,[a],[a])。
决定性地成功。:-)与
重复相同。
?是吗?@false:是的。有趣的是,我还没注意到。如果我正确阅读了8.15.3.1,只要用户点击
,重复/0
就不应该终止,而是产生
true
,对吗?的确。这是上世纪70年代旧TopLevel的一个特性:如果没有变量替换,只需停止即可;否。。。那么
change(a,a,[a],[a])
的两(2)个冗余答案呢?@false:有趣的事实:在Yap中,查询
?-change(a,a,[a],[a])。
决定性地成功。:-)与
重复相同。
?是吗?@false:是的。有趣的是,我还没注意到。如果我正确阅读了8.15.3.1,只要用户点击
,重复/0
就不应该终止,而是产生
true
,对吗?的确。这是上世纪70年代旧顶级水平的一个特点:如果没有变量替换,只需停止。你能确定这个吗?。。。理想情况下,在一个单独的答案,这已经阻止了关闭现在你可以做另一个答案!(顺便说一句,=可以用作运算符,
change1/4
不需要作为单独的谓词您可以确定吗?…理想情况下,在一个单独的答案中,该答案已被此关闭阻止,现在您可以做另一个答案!(顺便说一句,=可以用作运算符,
change1/4
不需要作为单独的谓词