使用递归方法并在 Prolog 中返回列表
Using recursion method and returning a list in Prolog
给定一个列表 L1
、位置 P
、元素 A
。我正在尝试 return 一个新列表,其中将元素 A
添加到列表 L1
和 return 中的位置 P
中,答案如下:
?- add_member(1,3,[2,3,4,5],A).
X=[2,3,1,4,5].
这是我的代码:
add_member(X, P, [H|T], NewList) :-
(P>1,
write('p>1 start | '),
P1 is P-1,
add_member(X, P1, T, Newlist1),
NewList is [H, Newlist1]),
write('p>1 end ');
(P=1,
write('p=1 start | '),
NewList is [X,H|T],
write('p=1 end | ')).
这里P
是位置,X
是要插入的元素。我已经使用 write('---')
来了解代码的工作原理(如调试)。 这是它的输出(有错误):
?- add_member(1,3,[2,3,4,5],x).
p>1 start | p>1 start | p=1 start |
ERROR: Type error: `[]' expected, found `[1,4,5]' (a list) ("x" must hold one character)
ERROR: In:
ERROR: [13] _22972 is [1,4|...]
ERROR: [12] add_member(1,1,[4,5],_23016) at /mnt/c/Users/mill/Documents/q2.pl:1
ERROR: [11] add_member(1,2,[3,4|...],_23058) at /mnt/c/Users/mill/Documents/q2.pl:5
ERROR: [10] add_member(1,3,[2,3|...],x) at /mnt/c/Users/mill/Documents/q2.pl:5
ERROR: [9] toplevel_call(user:user: ...) at /usr/lib/swi-prolog/boot/toplevel.pl:1117
这里,q2.pl
是文件名,toplevel.pl
是不可访问的。我正在为 linux (wsl) 使用 windows 子系统。
如何完成代码?我在这里缺少一个概念吗?
is/2
是一个内置谓词,它要求第二个参数是可算术解析的项(示例:3+6
、7*3
)。
在您的示例中,您使用 NewList is [H, Newlist1]
,其中第二个参数是列表而不是算术表达式。因此你会得到一个类型错误。您应该改用匹配运算符 =
。
你的代码的第二个问题是 [H, Newlist1]
构建了一个嵌套列表(它是一个长度为 2 的列表,第一个元素是 H
,第二个是列表 Newlist1
。这是您的代码的更正版本:
add_member(X, P, [H|T], NewList) :-
(P>1,
write('p>1 start | '),
P1 is P-1,
add_member(X, P1, T, Newlist1),
NewList = [H|Newlist1],
write('p>1 end '))
;
(P=1,
write('p=1 start | '),
NewList = [X,H|T],
write('p=1 end | ')).
再说两句:
在空列表的第一个位置插入元素也应该被捕获。
不建议在具有多个普通替代代码的 Prolog 子句中使用析取 (;
)(至少应谨慎使用)。因此,最好将您的子句分成两个子句(一个用于 P=1
,一个用于 P>1
):
add_member(X, 1, List, [X|List]).
add_member(X, P, [H|T], [H|NewList]) :-
P>1,
P1 is P-1,
add_member(X, P1, T, NewList).
给定一个列表 L1
、位置 P
、元素 A
。我正在尝试 return 一个新列表,其中将元素 A
添加到列表 L1
和 return 中的位置 P
中,答案如下:
?- add_member(1,3,[2,3,4,5],A). X=[2,3,1,4,5].
这是我的代码:
add_member(X, P, [H|T], NewList) :-
(P>1,
write('p>1 start | '),
P1 is P-1,
add_member(X, P1, T, Newlist1),
NewList is [H, Newlist1]),
write('p>1 end ');
(P=1,
write('p=1 start | '),
NewList is [X,H|T],
write('p=1 end | ')).
这里P
是位置,X
是要插入的元素。我已经使用 write('---')
来了解代码的工作原理(如调试)。 这是它的输出(有错误):
?- add_member(1,3,[2,3,4,5],x).
p>1 start | p>1 start | p=1 start |
ERROR: Type error: `[]' expected, found `[1,4,5]' (a list) ("x" must hold one character)
ERROR: In:
ERROR: [13] _22972 is [1,4|...]
ERROR: [12] add_member(1,1,[4,5],_23016) at /mnt/c/Users/mill/Documents/q2.pl:1
ERROR: [11] add_member(1,2,[3,4|...],_23058) at /mnt/c/Users/mill/Documents/q2.pl:5
ERROR: [10] add_member(1,3,[2,3|...],x) at /mnt/c/Users/mill/Documents/q2.pl:5
ERROR: [9] toplevel_call(user:user: ...) at /usr/lib/swi-prolog/boot/toplevel.pl:1117
这里,q2.pl
是文件名,toplevel.pl
是不可访问的。我正在为 linux (wsl) 使用 windows 子系统。
如何完成代码?我在这里缺少一个概念吗?
is/2
是一个内置谓词,它要求第二个参数是可算术解析的项(示例:3+6
、7*3
)。
在您的示例中,您使用 NewList is [H, Newlist1]
,其中第二个参数是列表而不是算术表达式。因此你会得到一个类型错误。您应该改用匹配运算符 =
。
你的代码的第二个问题是 [H, Newlist1]
构建了一个嵌套列表(它是一个长度为 2 的列表,第一个元素是 H
,第二个是列表 Newlist1
。这是您的代码的更正版本:
add_member(X, P, [H|T], NewList) :-
(P>1,
write('p>1 start | '),
P1 is P-1,
add_member(X, P1, T, Newlist1),
NewList = [H|Newlist1],
write('p>1 end '))
;
(P=1,
write('p=1 start | '),
NewList = [X,H|T],
write('p=1 end | ')).
再说两句:
在空列表的第一个位置插入元素也应该被捕获。
不建议在具有多个普通替代代码的 Prolog 子句中使用析取 (
;
)(至少应谨慎使用)。因此,最好将您的子句分成两个子句(一个用于P=1
,一个用于P>1
):add_member(X, 1, List, [X|List]). add_member(X, P, [H|T], [H|NewList]) :- P>1, P1 is P-1, add_member(X, P1, T, NewList).