在Prolog中定义谓词的最佳方法

时间:2011-12-31 09:04:07

标签: prolog iso-prolog

我在Prolog中定义过程时遇到问题。 我有两个源文件,并希望与他们两个咨询Prolog引擎。 这可以通过调用Prolog as swipl -g“['1.pl','2.pl']来完成。

这两个文件都是由另一个用另一种编程语言编写的程序生成的,我无法事先预测文件的确切内容。

问题在于其中一个文件总是有一条规则

predicate1(X):-predicate2(X).

但是,有时候是规则

predicate2(something):-body

在两个文件中都不存在,并且在为predicate1执行某些查询时,我得到一个错误“predicate2”未定义。

如果我包含该行

:- dynamic(predicate2/2). 

进入其中一个文件只有在另一个文件中没有定义谓词/ 2时才会有帮助(否则我会得到类似“你真的确定要重新定义谓词2/2吗?”。这里我不想要重新定义某些内容以保存另一个文件中的数据。

所以,我不知道如何使谓词“定义”。我需要一个SWI-Prolog或SICStus Prolog的解决方案。 (遗憾的是版本没有用于定义谓词的部分,例如visual Prolog)

3 个答案:

答案 0 :(得分:3)

您需要使用同名的ISO指令声明predicate2/2 multifile。因此,在每个文件中,您在predicate2/2的任何子句的顶部或之前写入:

:- multifile(predicate2/2).

这,无论你是否有该谓词的条款。


@CapelliC的建议绝对是一个危险的举动。如果您关闭所有存在错误,您将错过许多合法错误!

例如,您声明了dynamic(predicate2/2)但使用了predicate2(_)。你想要哪个arity?

答案 1 :(得分:2)

在SWI Prolog中,您可以避免错误。使用ISO内置

更改系统行为
:- set_prolog_flag(unknown, Choice).

选择是(失败,警告,错误)之一。

所以你的命令行将是:

swipl -g “set_prolog_flag(unknown,fail),['1.pl','2.pl']."

另一种可能性:定义虚假程序

swipl -g “assert(predicate2(_):-fail),['1.pl','2.pl']."

HTH

答案 2 :(得分:-1)

显然,Prolog无法回答我们提出的任何问题。例如,如果我们 问唐纳德是不是一只鸭子

?- isDuck(Donald) .
! ----------------------------------------
! Error 20 : Predicate Not Defined
! Goal : isDuck(_17610)
  

Prolog会回答说它对“某事”一无所知   是或不是鸭子。它发生的是逻辑谓词   isDuck/1未定义(Predicate Not Defined),因此Prolog不是   能够检查“某事物”是否是鸭子。我们将看到   后来,即使Prolog不知道鸭子是什么,也有可能   教它如何区分什么是鸭子和什么不是鸭子。   正如我们之前所说,Prolog是一种对话语言。在对话中   系统和程序员Prolog之间不仅能够   回答某些问题,但也能够了解它的作用   不知道。回答程序员Prolog提出的问题   检查知识库,其中所有内容都已注册Prolog   知道。在Prolog会议开始时,知识库保持不变   基本知识,包括其他事物,概念和   自然数算术的定义。会议期间是   有可能增加这种知识基础,包括定义和   Prolog不熟悉的概念(例如定义   一个鸭子),或者修改和扩展Prolog的定义   知道(例如,包括自然的新算术运算符)   号)。事实和规则表达了知识库。事实和规则   是一阶Horn子句的句法表示。所以   Prolog的知识是使用(几乎)首先使用   订单逻辑。这就是Prolog被称为逻辑的原因   语言。 Prolog中的程序是一组表达的事实和规则   某些知识。