【问题标题】:Prolog: Rules with nothing but anonymous variables in the head, and no bodyProlog:头部只有匿名变量的规则,没有正文
【发布时间】:2016-03-04 20:28:35
【问题描述】:

Prolog 的语法使用<head> :- <body> 格式的规则:

tree(G) :- acyclic(G) , connected(G). ,表示 G 的状态为树取决于状态为非循环和连接。

这个语法可以以一种隐含的方式扩展到事实。同样的例子:

connected(graphA) 建议connected(graphA):-true.

从这个意义上说,人们可以将 Prolog 事实松散地定义为始终为真的 Prolog 规则。

我的问题:在任何情况下,一个无实体的规则(在所有条件下都被假定为正确的规则)是否合适?从语法上讲,这样的规则如下所示。

graph(X).(建议graph(X):-true.

【问题讨论】:

  • 用你的术语来说,“无形规则”和“事实”有什么区别?
  • 无实体规则示例:blah(X)。事实示例(定义为无身体):blah(a)。注意第一个参数使用变量。
  • 我确实记得这些规则至少有一个有效用途:请参阅下面的答案。
  • 这个定义是“松散”的吗?
  • @ScottHunter,并非所有总是被假定为正确的规则(换句话说,没有实体)都符合事实。例如,我在下面的答案(成员)中的递归案例是无实体的,但不是事实。换句话说,没有实体的规则并不是事实。该定义是松散的,因为事实只是部分定义。

标签: prolog


【解决方案1】:

在回答之前,重新表述您的问题:

在 Prolog 中,您是否会编写一个头部只有匿名变量而没有正文的规则?

术语在这里很重要。 Facts 只是 rules 只有一个 head 而没有 body (这就是为什么你的问题有点混乱)。 匿名变量是您明确告诉编译器在谓词子句的上下文中忽略的变量(谓词子句是变量的语法范围)。如果您确实尝试将此谓词子句提供给 Prolog 编译器:

foo(Bar).

您将收到“单例变量”警告。相反,你可以写

foo(_).

这告诉编译器这个参数被故意忽略,并且不应该尝试与它进行变量绑定。

在操作上,当 Prolog 尝试证明规则时会发生什么?

  • 首先,统一规则头部的所有参数,这可能会导致新的变量绑定;
  • 然后,它尝试使用所有现有的变量绑定来证明规则的主体。

如您所见,第二步使其成为递归定义的算法:证明规则主体意味着证明其中的每个规则。

来到你的问题:这个的操作意义是什么:

foo(_).

有一个谓词foo/1,它适用于任何参数,因为在头部不需要进行变量绑定,而且总是因为不需要证明子目标。

我至少看到过这种规则的一种用法:查看this section of the SWI-Prolog manual 的最底部。小代码示例如下:

term_expansion(my_class(_), Clauses) :-
        findall(my_class(C),
                string_code(_, "~!@#$", C),
                Clauses).

my_class(_).

您应该阅读链接的文档以了解这样做的动机。代码本身的目的是在编译时将事实表添加到 Prolog 数据库中。这是通过术语扩展来完成的,这是一种代码转换机制,通常通过term_expansion/2 使用。您需要my_class/1 的定义,以便term_expansion/2 可以将其拾取、转换并用扩展代码替换它。我强烈建议你把上面的截图,放在一个文件中,查阅它并使用listing/1 看看有什么效果。我明白了:

?- listing(my_class).
my_class(126).
my_class(33).
my_class(64).
my_class(35).
my_class(36).

true.

NB:在本例中,您可以将出现的两次my_class(_) 替换为任何内容。你也可以这样写:

term_expansion(foobar, Clauses) :-
        findall(my_class(C),
                string_code(_, "~!@#$", C),
                Clauses).

foobar.

最终结果是相同的,因为操作意义是相同的。然而,使用my_class(_) 是自记录的,并且使代码的意图更加明显,至少对于作为 SWI-Prolog 的作者的经验丰富的 Prolog 开发人员来说是这样的;)。

【讨论】:

  • 太棒了,@鲍里斯。很有帮助。
【解决方案2】:

正如你所说,事实只是一个无形的规则。是的,有很多无形事实的用例:

  1. 表示静态数据
  2. 递归的基本情况
  3. 而不是一些花括号语言的伪代码

    布尔is_three(整数x){ if (x == 3) { 返回真; } 否则{返回假; } }

    我们可以简单地写

    是_三(3)。

【讨论】:

  • 看起来您在提交答案时可能遇到了问题 - 一旦您有机会重新访问,我很乐意听到您的想法。
  • 不确定你的意思是什么“问题”。
  • 第二次阅读后内容很好...起初由于某种原因格式化使帖子看起来不完整。我继续前进并迅速重新格式化。我会继续为您提供有用的帖子。
【解决方案3】:

这通常是递归定义的基本情况的表达方式。

【讨论】:

    【解决方案4】:

    为了突出我最初寻找的内容,我将为那些将来可能会问我最初问题的人提供以下简短答案。

    正如@Anniepoo 所建议的,无实体规则的一个示例是递归定义的基本情况。查看谓词的示例 member(X,L) 进行说明:

    member(X,[X|T]). /* recursive base case*/
    member(X,[H|T]):- member(X,T).
    

    这里,成员规则的第一个条目代表一个终止基本情况——感兴趣的项目 X 与剩余列表的头部匹配。

    我建议访问@Boris 的答案(已接受)以获得更完整的治疗。

    【讨论】:

    • 冒着学究气的风险,您的术语仍然有点过时。在您给出的member/2 示例中,只有一个谓词子句 没有主体,而不是规则!您可能想查看SWI-Prologs glossary of terms。您可能会注意到“规则”根本不存在;)
    • 谢谢。我会查看词汇表来复习。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    相关资源
    最近更新 更多