我经常在 Prolog 中编写代码,其中涉及一些算术计算(或在整个程序中很重要的状态信息),首先获取存储在谓词中的值,然后重新计算值,最后使用存储值retractall
,assert
因为在 Prolog 中,我们不能使用两次为变量赋值is
(因此几乎每个需要修改的变量都是全局的)。我开始知道这在 Prolog 中不是一个好习惯。对此我想问:
为什么在 Prolog 中这是一种不好的做法(尽管我自己不喜欢通过上述步骤只是为了拥有一种灵活的(可修改的)变量)?
有哪些一般方法可以避免这种做法?小例子将不胜感激。
PS我刚开始学习Prolog。我确实有 C 等语言的编程经验。
为进一步澄清而编辑
下面给出了我想说的一个不好的例子(在 win-prolog 中):
:- dynamic(value/1).
:- assert(value(0)).
adds :-
value(X),
NewX is X + 4,
retractall(value(_)),
assert(value(NewX)).
mults :-
value(Y),
NewY is Y * 2,
retractall(value(_)),
assert(value(NewY)).
start :-
retractall(value(_)),
assert(value(3)),
adds,
mults,
value(Q),
write(Q).
然后我们可以像这样查询:
?- start.
在这里,这是非常琐碎的,但在实际程序和应用中,上述全局变量的方法变得不可避免。有时,上面给出的列表如assert(value(0))
... 会变得很长,其中包含更多用于定义更多变量的断言谓词。这样做是为了使不同函数之间的值通信成为可能,并在程序运行期间存储变量的状态。
最后,我还想知道一件事:尽管您提出了各种避免方法,但上述做法何时变得不可避免?