带失败的回溯

2025年3月17日 | 阅读 3 分钟

当回溯或“标准”评估从左到右进行时,fail 谓词总是失败,正如其名称所暗示的那样。我们可以通过将其与 Prolog 的自动回溯结合使用,以查找数据库中具有指定属性的所有子句。

搜索 Prolog 的数据库

假设数据库中包含以下子句

使用谓词 alldogs,我们可以依次处理 dog 的每个子句,如下所示

当我们调用 alldogs 时,由于此 dog(A) 将与数据库中 dog 的子句匹配。 首先,变量 A 将绑定到原子 pug,并产生输出 'pug is a dog'。在谓词 alldogs 的第一个子句中,最终目标将导致评估失败。 然后,Prolog 将回溯两个目标 writenl,这些目标是不可满足的,直到 Prolog 到达 dog(A)。然后,第二次此目标成功,因此,变量 A 将绑定到 boxer。

此过程将继续,直到 pug、boxer 和 rottweiler 都已输出,并且评估再次失败。 在数据库中,没有更多的 dog,这次对 dog(A) 的调用也将失败。 因此,alldogs 的第一个子句将失败。 现在,Prolog 将检查 alldogs 的第二个子句,这将成功。 之后,评估将停止。

由于这种效果,Prolog 将生成一个循环来遍历数据库。 为了满足目标 dog(A),Prolog 将找到 A 的所有可能值。

对于谓词 alldogs,第二个子句非常重要。 它用于确保在搜索数据库后目标成功。 它只会使用第一行成功,任何对谓词 alldogs 的调用最终都会失败。


下一个程序用于搜索包含子句的数据库。 这些子句包含许多人的姓名、职业、居住地和年龄。

假设数据库中包含以下五个子句

使用 allteachers 谓词,我们可以找到所有教师的姓名。

在这种情况下,使用回溯和失败的效果是在数据库中查找所有教师。

找到了两位教师,如果我们省略 allteachers 的第二个子句,则 allteachers 的评估将以失败结束。 如果目标是在系统提示符下输入的,这并不重要。 在规则的主体中,如果将 allteachers 用作目标,则可以确保它始终成功。

要搜索数据库,并非总是需要使用“回溯和失败”。 例如,我们将使用 somepeople/0 谓词在数据库中查找所有人。 为此,我们将下降到 jolie,仅使用标准回溯。

如果变量 Lastname 绑定到 jolie,则目标 Lastname= jolie 将成功。 如果不是,它将失败。 其效果是搜索数据库,直到并包括第二个参数为 jolie 的 person 子句。


下一个主题The Cut Predicate