我得到的代码必须运行数据库,只要N>订购。 我的代码只运行一次:/?
display(N) :-
w(Order,_,Word,Class),
N > Order -> (write(Word), write(' '), write(Class)),
nl, fail .
提前致谢!
答案 0 :(得分:4)
您的问题是您使用->
首先,代码被解释为:
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)).
但是,这将检查整个数据库并打印N>Order
。如果这是理想的行为,你的描述有点不清楚,但如果你想停在第一个更大的元素,你可以做类似的事情:
display2(N) :-
catch((forall(w(Order, _, Word, Class),
(N > Order ->
writef("%t %t \n", [Word,Class]); throw(end))), end, true)).
不是最具说服力的方式,但我不确定在不知道w/4
是什么的情况下对其进行建模的最佳方式是什么(我认为它是一些prolog子句但它可能是一个谓词访问一个DB虽然是ODBC层)
答案 1 :(得分:3)
我认为你忘了'else'分支,并且( - >)/ 2的优先级高于(,)/ 2,它会抑制预期的顺序。尝试
display(N) :-
w(Order,_,Word,Class),
( N > Order -> write(Word), write(' '), write(Class), nl ; true ),
fail .