在Prolog中使用递归方法并返回一个列表

3

给定一个列表L1,一个位置P和一个元素A。我试图返回一个新的列表,在其中将元素A添加到列表L1的位置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无法访问。我正在使用Windows子系统Linux (WSL)。

我该如何完成代码?这里有什么概念我没有掌握吗?

1个回答

4

is/2 是内置谓词,要求第二个参数是一个可以进行算术运算的项(例如:3+67*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 | ')).

还有两点需要注意:

  • the insertion of an element at the first position of an empty list should be captured as well.

  • using disjunction (;) within a Prolog clause with more than a trivial alternatives code is not recommended (at least it should be used with care). Thus it is better to split your clause in two clauses (one for P=1 and one for 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).
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接