Prolog数据库:为什么程序只运行一次?

时间:2012-10-12 10:12:18

标签: database prolog

我得到的代码必须运行数据库,只要N>订购。 我的代码只运行一次:/?

display(N) :-
    w(Order,_,Word,Class),
    N > Order -> (write(Word), write(' '), write(Class)),
    nl, fail .

提前致谢!

2 个答案:

答案 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 .