Ed *_*Man 6 prolog xsb iso-prolog
如何模拟软切割 I* - > T; E在ISO Prolog中?我有副作用,所以我不能多次调用它.
除了最后一个要求,我认为以下定义有效:
if_(I, T, E) :-
not(not(I)) ->
call((I, T));
call((not(I), E)).
Run Code Online (Sandbox Code Playgroud)
(我实际上正在使用XSB prolog; XSB的解决方案对我也很有用.)
是的,我们可以在 ISO Prolog 甚至 XSB 中实现这一点,但效率不高。为了提高效率,您需要一些“选择性剪切”。此外,XSB 不实现符合 ISO 的整数,因此必须单独处理溢出。
:- dynamic(if_counter/1).
if_counter(0).
:- dynamic(no_if_answer/1).
if(If_0, Then_0, Else_0) :-
once(if_counter(Id)),
Idx is Id+1,
( Idx > Id -> true
; throw(error(representation_error(max_integer),
'XSB misses ISO conforming integers'))
),
retractall(if_counter(_)),
asserta(if_counter(Idx)),
asserta(no_if_answer(Id)),
( If_0,
retractall(no_if_answer(Id)),
Then_0
; retract(no_if_answer(Id)) ->
Else_0
).
Run Code Online (Sandbox Code Playgroud)
低效率的主要原因是对于确定的条件If_0,仍然存在一个选择点。可以想象,一旦执行,实施可能会得出总是失败的结论,retract(no_if_answer(Id))但我怀疑实施者是否会投资于此类优化。retractall(no_if_answer(Id))编辑:这看起来极不可能的原因是实现必须保证断言的数字总是上升。
请注意,软剪切会像剪切一样产生不完整性。考虑:
| ?- if(X = a, T = equal, T = not_equal).
X = a
T = equal;
no
Run Code Online (Sandbox Code Playgroud)
这显然错过了答案!要了解原因,请执行以下操作X = b:
| ?- X = b, if(X = a, T = equal, T = not_equal).
X = b
T = not_equal;
no
| ?- if(X = a, T = equal, T = not_equal), X = b.
no % bad!!
Run Code Online (Sandbox Code Playgroud)
连接词应该是可交换的(模非终止、错误、副作用)。
如果您对声明性的健全条件感兴趣,这些条件也非常高效并且通常比不纯的条件更快,请考虑if_/3。请library(reif)参阅 SICStus,它给出了所有正确答案:
| ?- if_(X = a, T = equal, T = not_equal).
X = a,
T = equal ? ;
T = not_equal,
prolog:dif(X,a) ? ;
no
Run Code Online (Sandbox Code Playgroud)