我开始学习序言。我想在列表中的每个偶数后面添加 1。这是我的代码:
member(E,[E|_]).
member(E,[_|T]):-
member(E,T).
add([],[]).
add([H|T],[H|[1|T1]]):-
H mod 2=0,!,
add(T,T1).
add([H|T],[H|T1]):-
add(T,T1).
我尝试了 add([5,6,7],[5,6,1,7]) 、 add([5,6,7],[5,1,6,7]) 等,但是我得到的只是假,假,假。请帮忙!
最佳答案
您还可以选择使用 DCG 来描述此类列表。考虑以下代码:
:- use_module(library(clpfd)).
list_inserted(L,I) :-
phrase(inserted(L),I). % the DCG inserted//1 describes I based on L
inserted([]) --> % if L is empty
[]. % I is empty
inserted([X|Xs]) --> % if the head of the list L
{X mod 2 #= 0}, % is even
[X,1], % it's in the list I followed by 1
inserted(Xs). % the same holds for the tail
inserted([X|Xs]) --> % if the head of the list L
{X mod 2 #= 1}, % is odd
[X], % it's in the list I
inserted(Xs). % the same holds for the tail
如果您使用示例查询此谓词,它将产生所需的结果:
?- list_inserted([5,6,7],I).
I = [5, 6, 1, 7] ;
谓词也适用于另一个方向:
?- list_inserted(L,[5,6,1,7]).
L = [5, 6, 7] ;
false.
?- list_inserted(L,[5,1,7]).
L = [5, 1, 7] ;
false.
然而,最常见的查询是以不公平的方式列出解决方案:首先列出仅包含偶数元素的列表。由于其中有无限多个,因此您永远不会看到包含奇数元素的列表:
?- list_inserted(L,I).
L = I, I = [] ;
L = [_G762], % <- [even]
I = [_G762, 1],
_G762 mod 2#=0 ;
L = [_G847, _G850], % <- [even,even]
I = [_G847, 1, _G850, 1],
_G847 mod 2#=0,
_G850 mod 2#=0 ;
L = [_G932, _G935, _G938], % <- [even,even,even]
I = [_G932, 1, _G935, 1, _G938, 1],
_G932 mod 2#=0,
_G935 mod 2#=0,
_G938 mod 2#=0 .
.
.
.
您可以通过添加目标长度/2 前缀来改进这一点。这样,对于每个列表长度,都会生成奇数和偶数元素的所有可能组合:
?- length(L,_), list_inserted(L,I).
L = I, I = [] ;
L = [_G65], % <- [even]
I = [_G65, 1],
_G65 mod 2#=0 ;
L = I, I = [_G180], % <- [odd]
_G180 mod 2#=1 ;
L = [_G110, _G113], % <- [even,even]
I = [_G110, 1, _G113, 1],
_G110 mod 2#=0,
_G113 mod 2#=0 ;
L = [_G228, _G231], % <- [even,odd]
I = [_G228, 1, _G231],
_G228 mod 2#=0,
_G231 mod 2#=1 ;
L = [_G265, _G268], % <- [odd,even]
I = [_G265, _G268, 1],
_G265 mod 2#=1,
_G268 mod 2#=0 ;
L = I, I = [_G262, _G265], % <- [odd,odd]
_G262 mod 2#=1,
_G265 mod 2#=1 ;
.
.
.
关于Prolog - 在列表中的偶数元素后添加 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46895789/