Prolog - 在列表中的偶数元素后添加 1

标签 prolog

我开始学习序言。我想在列表中的每个偶数后面添加 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/

相关文章:

list - 为什么改变事实的顺序会改变谓词的行为?

prolog - 在 Prolog 中断言数字谓词

prolog - 如何像在 Prolog 中一样在 Mercury 中生成新变量列表?

encoding - 序言中的谓词编码

prolog 从一个化合物中得到一个术语

检测路径的 Prolog 定义

recursion - 递归地将每隔一个元素移动到列表的末尾

prolog - 从 gerrit 审查中排除作者

Prolog - 使用 DCG 解析

prolog中的矩阵乘法