我得到了这个代码,只要 N > Order 就必须运行数据库。我的代码只运行一次:/?
display(N) :-
w(Order,_,Word,Class),
N > Order -> (write(Word), write(' '), write(Class)),
nl, fail .
提前致谢!
你的问题是你使用的方式->
首先,代码被解释为:
display(N) :-
( w(Order,_,Word,Class),
N > Order )
) ->
( write(Word),
write(' '),
write(Class)
),
nl, fail .
->
破坏选择点,这意味着它不会w/3
再次尝试调用。
你可以(可能)让它像这样工作:
display(N) :-
(w(Order,_,Word,Class),
N > Order )-> (write(Word), write(' '), write(Class)),
nl, fail .
但最终它是非常丑陋的代码,而且如您所见,容易出现错误。更好的方法是使用forall/2
:
display2(N) :-
forall(w(Order, _, Word, Class),
(N > Order ->
writef("%t %t \n", [Word,Class]); true)).
尽管如此,这将检查整个数据库并打印 if N>Order
。从您的描述中有点不清楚这是否是所需的行为,但如果您想停在第一个更大的元素上,您可以执行以下操作:
display2(N) :-
catch((forall(w(Order, _, Word, Class),
(N > Order ->
writef("%t %t \n", [Word,Class]); throw(end))), end, true)).
不是最具声明性的方法,但我不确定在不知道是什么的情况下建模它的最佳方法是什么w/4
(我假设它是一些序言子句,但它可能是通过 ODBC 层访问数据库的谓词)
我认为您忘记了“其他”分支,并且 (->)/2 的优先级高于 (,)/2,从而抑制了预期的顺序。尝试
display(N) :-
w(Order,_,Word,Class),
( N > Order -> write(Word), write(' '), write(Class), nl ; true ),
fail .