我正在使用Prolog编写一个小程序。我想重用一个数据结构,所以我尝试将它分配给变量:
CitizenProfile = voter_profile(citizen,not_in_prison).
然后我像这样使用它:
state(alabama, [CitizenProfile]).
但是,当我从控制台编译文件时遇到此错误:
**[No permission to modify static_procedure `(=)/2'][1]**
==
我甚至尝试声明等号动态,但这并没有解决任何问题。 :(
:- dynamic (=)/2.
答案 0 :(得分: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/2
和O(N)搜索,这将导致非常糟糕的性能。默认情况下,Prolog将对第一个参数进行索引,但是每个实现都定义了一些索引声明,您可以使用这些声明来为其添加或替代索引第二个或第N个参数。如果您需要所有结果,则可以使用bagof/3
或findall/3
重新构建列表。
答案 1 :(得分:0)
您可能想要的是定义动态谓词voter_profile/2
和assertz
新事实“动态”以便由该谓词存储(子句数据库)记住。我说“可能”是因为你还没有说清楚一个州(例如阿拉巴马州)应该如何与特定的公民形象相关。
有关SWI-Prolog内置assertz/1
文档以及有关SWI-Prolog数据库机制的更多信息,请参阅here。