一点没有特别含义的测试代码:
:- use_module(library(chr)).
:- chr_constraint foo/1, bar/1, anyone/2.
foo(X) \ bar(Y) <=> anyone(X,Y).
anyone(_,Y) <=> bar(Y) | writef("bar(%w) exists\n",[Y]).
anyone(_,Y) <=> writef("bar(%w) does not exist\n",[Y]).
如果从 SWI Prolog 命令行查询上述内容,然后运行:
?- foo(8),bar(10).
一段时间后溢出:
Could not reenable global-stack
Could not reenable global-stack
ERROR: Out of global-stack.
ERROR: No room for exception term. Aborting.
Could not reenable global-stack
ERROR: Out of global-stack.
ERROR: No room for exception term. Aborting.
ERROR: Execution Aborted
% Execution Aborted
但是,如果通过将测试bar
从守卫移到头部来更改第二条规则的代码:
:- use_module(library(chr)).
:- chr_constraint foo/1, bar/1, anyone/2.
foo(X) \ bar(Y) <=> anyone(X,Y).
anyone(_,Y),bar(Y) <=> writef("bar(%w) exists\n",[Y]). % changed!
anyone(_,Y) <=> writef("bar(%w) does not exist\n",[Y]).
然后执行终止:
?- foo(8),bar(10).
bar(10) does not exist
foo(8).
这是实施的意外吗?这似乎有点冒险。
此外,编写上述代码是因为我想测试要从存储中删除的约束(此处为bar(Y)
)是否在规则主体中可用。显然不是,在规则体执行时它已经消失了;但是这个实现是依赖于 CHR 的还是必要的或指定的行为?