0

我正在使用 Prolog 编写一个小程序。有一个我想重用的数据结构,所以我尝试将它分配给一个变量:

CitizenProfile = voter_profile(citizen,not_in_prison).

然后我像这样使用它:

state(alabama, [CitizenProfile]).

但是,当我从控制台编译文件时遇到此错误:

**[No permission to modify static_procedure `(=)/2'][1]**
==

我什至尝试声明等号动态,但这并没有解决任何问题。:(

:- dynamic (=)/2.
4

2 回答 2

2

错误的原因是 Prolog 看起来像您正在尝试执行此操作:

=(CitizenProfile, voter_profile(citizen,not_in_prison)).

这看起来就像任何其他事实定义一样。=/2可以很容易地foobar/2

foobar(CitizenProfile, voter_profile(citizen,not_in_prison)).

现在,如果我们处于某个规则体的中间,这可能是建立变量绑定的合法方式。然后一切都将在此达到高潮:

foo :- ...,
    CitizenProfile = voter_profile(citizen,not_in_prison),
    state(alabama, [CitizenProfile]).

这和这样说是一样的:

foo :- ...,
    state(alabama, [voter_profile(citizen,not_in_prison)]).

如果这个扩展是你想要完成的,那么不幸的是没有办法在这样的事实数据库中创建速记。正如@hardmath 所说,您可以使用assertz/1它来完成它,如下所示:

make_database :-
    CitizenProfile = voter_profile(citizen,not_in_prison),
    assertz(state(alabama, [CitizenProfile])).

不过,这将是一种粗略的行为,因为您将静态信息放入动态存储中。以我的经验,人们通常不想在数据库中建立大型结构。建立多个关系并以关系方式在它们之间“加入”通常更清洁、更容易。我不确定你在这里想要什么,所以这只是一个草图,但这是我希望看到的:

voter_profile(voter1, alabama,    citizen, not_in_prison).
voter_profile(voter2, alabama,    citizen, in_prison).
voter_profile(voter3, new_mexico, citizen, not_in_prison).

而不是我认为你会(最终)建造的东西,我更喜欢这样:

 state(alabama,   [voter_profile(citizen,not_in_prison), voter_profile(citizen, in_prison)]).
 state(new_mexico,[voter_profile(citizen,not_in_prison)]).

创建一堆列表的诱惑是可以理解的,但是 Prolog 的数据库并不能真正帮助您处理它们。你最终会诉诸大量的member/2O(N) 搜索,这会导致性能非常糟糕。默认情况下,Prolog 将对第一个参数进行索引,但每个实现都定义了一些索引声明,您可以使用它来使其索引第二个或第 N 个参数。然后,如果您需要所有结果,您可以使用bagof/3findall/3重新构建列表。

于 2013-09-13T19:48:29.720 回答
0

可能您想要的是定义一个动态谓词voter_profile/2assertz“动态”新的事实以由该谓词存储(子句数据库)记住。我说“可能”是因为您没有明确说明一个州(例如阿拉巴马州)应该如何与特定的公民资料相关联。

有关SWI-Prolog 内置文档以及更多有关 SWI-Prolog 数据库机制的信息,请参见此处。assertz/1

于 2013-09-12T14:57:34.220 回答