我有一个动态列表:
:- dynamic queue/1.
queue([Bob,Steve,Richard,Katie]).
和谓词:
delete_person(Person) :-
queue(Q),
retractall(queue(_)),
delete(Q, Person, Z),
assert(queue(Z)).
从逻辑上讲,这跟随我,但我显然犯了一个错误,因为在运行谓词delete_person
之后列表保持不变
答案 0 :(得分:1)
此代码段中存在多个问题。首先,您已发布以下程序:
:- dynamic queue/1. queue([Bob,Steve,Richard,Katie]). delete_person(Person) :- queue(Q), delete(Q, Person, Z). assert(queue(Z)).
这意味着您的代码中包含parameter-clause → () | (parameter-list)
parameter-list → parameter | parameter,parameter-list
形式的事实。那可能不你打算写什么。
其次,如果你更正assert/1
阅读:
delete_person(Person) :- queue(Q), delete(Q, Person, Z), assert(queue(Z)).
然后我们仍然有以下单身警告:
Singleton variables: [Bob,Steve,Richard,Katie]
这是因为delete_person/1
,Bob
等都是(可能是无意中)Prolog 变量。
如果你更正这一点,请阅读:
queue([bob,steve,richard,katie]).
然后至少程序编译时没有警告。
现在我们可以谈谈实际问题:
?- delete_person(bob). true. ?- queue(Q). Q = [bob, steve, richard, katie] ; Q = [steve, richard, katie].
下次请包括:
在上述情况中,为什么队列未被修改?
这是因为您无意中只为Steve
添加了一个额外的事实,但您不会删除已存在的事实。
修改全局数据库时出现典型错误。如果您像使用命令式语言一样使用Prolog,您已经可以瞥见等待您的问题。这将使你的代码非常难以推理,产生几个难以调试的问题,使你很难测试代码,并且通常将命令式语言的缺点与严重缺乏通用性结合起来。
您的程序的声明性解决方案是根据队列之间的关系进行思考。可以这样想一下:如果从第一个队列中删除了一个特定元素,那么2个队列之间的 relation 是什么?第二个队列与第一个队列相同,除了那个元素?
例如,考虑一下:queue/1
,其定义可以这样开始:
queue_without_element(Q0, E, Q) :- ...
优点: