【问题标题】:Prolog insert element issueProlog插入元素问题
【发布时间】:2016-02-26 13:05:50
【问题描述】:

所以我有 Prolog 代码在给定位置插入一个元素:

ins(Val, [H|List], Pos, [H|Res]):-
   Pos > 1,
   !, 
   Pos1 is Pos - 1, 
   ins(Val, List, Pos1, Res). 
ins(Val, List, 1, [Val|List]).

这给出了一个输出

28 ?- ins(B, [A,C,D], 4, Z).
Z = [A, C, D, B].

效果很好。

现在我想在列表的开头重用这段代码。

addFirst(Val, [H|List], [H|Res]):-
   ins(Val, [H|List], 1, [H|Res]).

这给了我一个输出

41 ?- addFirst(A, [B,C,D], Z).
A = B,
Z = [B, B, C, D].

有人可以帮我解释一下为什么会这样吗?我是 Prolog 的新手。

【问题讨论】:

  • 如果您确保您的大小写正确,将会很有帮助。变量以大写字母开头,原子以小写字母开头。你所拥有的一切都是大写的。难怪事情不起作用。你能修复你的代码吗?
  • @Enigmativity 案例是错误的一部分;在这方面修复代码将向 OP 揭示错误的性质,但会改变问题的含义。

标签: list prolog


【解决方案1】:

该错误是 H 的过度共享... 越详细越好:这行得通

addFirst(Val,List,Res):-
    ins(Val,List,1,Res).

【讨论】:

    【解决方案2】:

    您面临的问题是您的代码没有正确反映您的意图。

    addFirst(Value, List, Result) :-
       ins(Value, List, 1, Result).
    

    如果您想添加一个值作为列表的第一个值,请将其插入到列表的位置 1。这就是上面的语句所说的,这就是所需要的。


    您注意到的错误源于两个错误。

    第一个是addFirst 的规则。

    addFirst(Val,[H|List],[H|Res]):-
       ins(Val,[H|List],1,[H|Res]).
    

    这表明两个列表的头部应该相同。换句话说,你有一个列表[H|List],你在第一个位置添加Val,你期望结果是[H|Res]。发生这种情况的唯一方法是当要添加的值是它要添加到的列表的头部时。

    这就是第二个错误发挥作用的地方。

    41 ?- addFirst(A,[B,C,D],Z).
    A = B,
    Z = [B, B, C, D].
    

    您使用的是大写字母。大写字母表示变量。因此,Prolog 解释器尝试以使addFirst(A,[B,C,D],Z) 为真的方式为这些变量赋值。正如我们刚刚看到的,这一定意味着列表的头部必须等于添加的值,所以A = B,这是回复的第一部分。第二部分是结果列表,也就是列表(由变量组成!)[B, B, C, D].

    如果您的列表和新元素使用小写字母,此查询将失败。

    41 ?- addFirst(a,[b,c,d],Z).
    No.
    

    【讨论】:

    • 我真的很喜欢这个解决方案和解释。在我的脑海中清除了很多。谢谢
    【解决方案3】:

    你应该看看 nth[0,1]/4 :

     ?- nth0(3, R, z, [a,b,c] ).
    R = [a, b, c, z].
    

    这可能会有所帮助。

    【讨论】:

    • 我知道这一点,但我需要自己实现它。不过谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多