关于Prolog中的规则

4

在我的程序中,我有一些规则,比如:

tellme(X) :- knows(X).
tellme(friends1(X)) :-  tellme(X).
tellme(friends2(X)) :-  tellme(X).
tellme(friends3(X)) :-  tellme(X).
.
.
.
tellme(friends25(X)) :- tellme(X).

现在这些 friends1,friends2,friends3……都依赖于变量 N。例如,我的 N 的值是 25。那么是否可以编写一个规则来生成这些规则直到 N,还是我必须手动为 N 次编写这些规则。欢迎任何建议或解决方案。非常感谢您的关注。
2个回答

2

在大多数现代Prolog环境中,您可以使用术语扩展通用运算符的帮助生成任何类型和数量的代码。以下示例适用于SWI:

term_expansion(gen_tellme(N), Terms) :-
    findall((tellme(F) :- tellme(X)),
            (between(1, N, I), atom_concat(friend, I, Fi), F =.. [Fi, X]),
            Terms).

gen_tellme(25). % generates 25 copies of the tellme clause.

话虽如此,将信息嵌入谓词名称中,即朋友编号,通常不是一个好的设计。为什么不使用friend(N, X)重写代码,其中N是数字?


但是它给了我这个错误:ERROR: toplevel: Undefined procedure: gen_tellme/1 (DWIM无法纠正目标) - anilonwebs
@anilonwebs:你需要在同一个文件中同时查询这两个谓词。第一个定义了一个术语扩展规则,而第二个则使用它。“gen_tellme()”被扩展了,它并不成为一个真正的谓词。不要试图从提示符中执行此操作,请将其放入文件中。 - Little Bobby Tables
请看一下基础情况缺失的第一条规则,即我问题部分中的第一条。因此,我将其添加到一个文件中: tellme(X) :- 知道(X)。知道(anil)。 使用你定义的规则。但当我查询 tellme(friends1(anil)) 时,它给出了错误的结果。我已经在一个单一的文件中编写了所有的代码。 - anilonwebs
@anilowebs:这是一种类型:我写成了“friend”而不是“friends”。 - Little Bobby Tables

1

你可以尝试使用一个二元函数符号friends(N,X)代替每个N的函数符号。你可能还想将tellmeknows改为接受两个参数的形式。(对我来说,knows(X)没有直接的意义,所以我不完全明白你的意图。)

如果出于某种原因,这不是你想要的,你可以使用类似以下代码的新函数符号(未经测试):

friends_functor(N, Functor) :-
    number(N),
    atom_concat(friend, N, Functor).

然后使用 assertaassertz。虽然我真的不明白为什么你会想这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接