【问题标题】:Prolog not showing output in correct formatProlog 未以正确格式显示输出
【发布时间】:2014-04-13 02:01:29
【问题描述】:

我是 Prolog 的新手,我正在尝试从列表中删除最后一个元素。我试过的代码:

removeLast([],[_]).
removeLast([_|T], [_|OT]):-removeLast(T, OT).

here 获得。我从 SWi Prolog 执行了代码,得到了一个奇怪的输出......

1 ?- 
|    removeLast(X, [1,2,3,4]).
X = [_G299, _G302, _G305] .

这应该显示 [1,2,3],而不是显示一些数字(?)

我不知道我做错了什么,为什么它以这种格式显示?我尝试了所有我知道的谷歌组合来搜索这个词,尽管我看到人们在他们的查询中直接使用这种格式,比如parent(X, _G3248)

更新:感谢@lurker,将代码修改为原始格式可以正确输出:

removeLast([],[_]).
removeLast([X|T], [X|OT]):-removeLast(T, OT).

15 ?- removeLast(X, [1,2,3,4]).
X = [1, 2, 3] 

但是谁能解释一下,_G3240 是什么?

【问题讨论】:

  • 您编写的内容与您提供的链接中的代码不同。你为什么在第二个子句中使用_,你知道什么时候这样做合适吗?链接中的解决方案没有在第二个子句中使用它是有原因的。
  • 如有错误请指正。正如我所说,我是序言的新手。我知道_ 用于空占位符?就像我不想在那里使用“未使用的变量”一样?
  • 对。这是一个“占位符”,在这种情况下,每个_ 都是不同的。但是,在原始解决方案中,它在两个地方都使用了X。这两个地方的价值相同,而且非常重要。它不是未使用的。当一个变量在一个子句中出现多次时,它的值在所有情况下都被实例化。这就是为什么原始解决方案在第二个子句中没有使用_ 的原因。你可以发送trace 看看会发生什么。
  • @lurker 我修改了代码,得到了输出。你能解释一下 _G302吗?它的名称是什么,何时何地使用?
  • _G302 等是 SWI Prolog 显示“无关”变量的方式,但可能有几个不同的变量。所以他们有不同的数字。您的第一次尝试生成了几个“无关”变量。在提示符下试试这个:X = [_,_,_]..

标签: list prolog output


【解决方案1】:

以下是解决方案行为的不同之处。让我们来看看有故障的那个。

removeLast([],[_]).

这条规则说如果我有一个元素的列表,那么删除最后一个元素的对应列表是[],我不在乎那个元素是什么(它甚至可以是一个变量)。这是真的,也是一个有效的规则。

removeLast([_|T], [_|OT]) :- removeLast(T, OT).

这条规则说[_|T][_|OT],如果我不关心它们的第一个元素是什么,则删除最后一个元素,TOT,删除最后一个元素(遵循相同的规则)。这听起来不太对劲。这意味着如果我从列表中删除最后一个元素,我不在乎我的结果中有什么元素。所以你得到一个任意的元素列表,其数量比你的原始列表少一。但是这些元素与原始列表前面的元素不匹配。在 Prolog 中,两个_ 实例是不同 匿名变量。它们并不统一。

更正的子句是:

removeLast([X|T], [X|OT]) :- removeLast(T, OT).

这表示列表[X|T] 是列表[X|OT] 删除了最后一个元素如果 T 是列表OT 删除了最后一个元素。常见的X 表示它们共享相同的列表头,这是正确的。当递归到达第二个参数的最后一个元素时,第一个子句被匹配并且单个元素尾部被空列表[] 替换。然后你会得到正确的最终结果。

我将_ 变量称为“匿名”而不是“无关紧要”,因为匿名变量在某些用途中的值确实很重要。通常,就像在这种情况下,它们在不使用值时使用。

【讨论】:

  • @GopikrishnaS 没问题!我知道_ 一开始可能会有点混乱,尤其是当周围有多个时。
猜你喜欢
  • 2020-03-30
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
相关资源
最近更新 更多