【问题标题】:Prolog recursive predicate overwriting return valuesProlog 递归谓词覆盖返回值
【发布时间】:2013-05-28 11:51:24
【问题描述】:

我有一个递归谓词:

something(A, Object, Value, Complete) :-
     member(Value, Complete), Object = Value.

something(A, Object, _, Complete) :-
    objects(Object),
    \+ member(Object, Complete),
    !,
    <Predicates to get return values>,
    something(A, NewObject, Object, [Object|Complete]).

这个谓词的作用是遍历Object的所有事实,对其进行进一步的逻辑处理,然后输出每个Object事实的结果。

我遇到的问题是我得到的所有返回值(按下 ;)都是第一次迭代,所以这个递归函数为 Object 返回的第一个值。

EG:我看到的输出:

Object: obj1
Object: obj1

它应该在哪里

Object: obj1
Object: obj2

(与其他变量一起,但我将它们排除在外以保持帖子更清洁)。

在 SWI Prolog 实现中使用可视化调试器后,我可以看到,一旦内部递归调用返回,内部递归的值就会丢失,这就是为什么我再次看到 obj1 作为第二个返回值。

我不太确定如何保存这些内部值,我查看了很多递归函数的示例,但似乎无法将这些概念应用于这个特定实例。

【问题讨论】:

  • 似乎是findall(Object, &lt;Predicates to get return values&gt;, Complete)的工作

标签: recursion prolog


【解决方案1】:

我认为这里对变量存在简单的误解。 Prolog 有变量,而不是“assignables”。没有区别

something(A, Object, Value, Complete) :-
    member(Value, Complete), Object = Value.

还有这个:

something(A, Value, Value, Complete) :-
    member(Value, Complete).

一个自然的结果是这条线:

something(A, NewObject, Object, [Object|Complete]).

和这个是一样的:

something(A, Object, Object, [Object|Complete]).

这几乎肯定是您看到意外行为的地方。如果您的想法拒绝这一点,并且您觉得我的简化版本和您的代码之间应该存在差异,那么您误解了 Prolog 中变量的工作方式。它们在任何情况下都不能被“覆盖”。在递归调用中,它们可以以不同的方式实例化,但这与任何其他语言中的形式参数实际上并没有什么不同。

【讨论】:

    猜你喜欢
    • 2018-10-09
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多