Prolog 序言中的斐波那契-如果为False,则中断
我有一个程序fib(X,Y)。如果Y是第X个斐波那契数,则返回Prolog 序言中的斐波那契-如果为False,则中断,prolog,fibonacci,Prolog,Fibonacci,我有一个程序fib(X,Y)。如果Y是第X个斐波那契数,则返回True,否则应返回False。每当我输入错误的语句时,我的程序就会中断 fib(R,V) :- fib(0,1,R,V). fib(X, Y, 0, V) :- Y == V. fib(X, Y, R, V) :- Z is X + Y, C is R - 1, fib(Y, Z, C, V). fib(0,1) -> True fib(1,1) -> True fib(2,2) -> True fib(3,3)
True
,否则应返回False
。每当我输入错误的语句时,我的程序就会中断
fib(R,V) :- fib(0,1,R,V).
fib(X, Y, 0, V) :- Y == V.
fib(X, Y, R, V) :- Z is X + Y, C is R - 1, fib(Y, Z, C, V).
fib(0,1) -> True
fib(1,1) -> True
fib(2,2) -> True
fib(3,3) -> True
fib(4,5) -> True
fib(3,5) -> Won't finish.
我做错了什么?我正在使用运行我的程序查询 这里的问题是您编写了两个子句
fib(X,Y,0,V):-
和fib(X,Y,R,V):-
。Prolog使用回溯:如果一个子句已经尝试过,它将——不管成功与否——稍后也会重试下一个子句(有一些元谓词,如once/1
,可以改变这一点)
因此,即使R
为0
或更低,Prolog也会尝试第二个子句
解决此问题的快速方法是使用第二条的防护装置:
fib(_, Y, 0, V) :-
Y == V.
fib(X, Y, R, V) :-
R > 0,
Z is X + Y,
C is R - 1,
fib(Y, Z, C, V).
但是现在我们仍然没有一个双向关系:我们不能得到给定值V的X。这更复杂。最简单的方法可能是为此使用clpfd
:
:- use_module(library(clpfd)).
fib(_, V, 0, V).
fib(X, Y, R, V) :-
R #> 0,
V #>= Y,
Z is X + Y,
C #= R - 1,
fib(Y, Z, C, V).
?- fib(2,B).
B = 2 ;
false.
?- fib(10,B).
B = 89 ;
false.
?- fib(A,1).
A = 0 ;
A = 1 ;
false.
?- fib(A,2).
A = 2 ;
false.
?- fib(A,3).
A = 3 ;
false.
?- fib(A,4).
false.
?- fib(A,5).
A = 4 ;
false.
?- fib(4,5).
true ;
false.
?- fib(4,6).
false.
?- fib(4,10).
false.
?- fib(5,8).
true ;
false.
您是否尝试进行
跟踪
以查看发生了什么?您可能还想考虑:如果R<0
,会发生什么?您的第二个fib/4
子句仍将执行。如何运行跟踪?输入trace.
然后运行查询。Prolog文档对此进行了解释。如果不想再跟踪,请输入notrace.
?- fib(A,1).
A = 0 ;
A = 1 ;
false.
?- fib(A,2).
A = 2 ;
false.
?- fib(A,3).
A = 3 ;
false.
?- fib(A,4).
false.
?- fib(A,5).
A = 4 ;
false.
?- fib(4,5).
true ;
false.
?- fib(4,6).
false.
?- fib(4,10).
false.
?- fib(5,8).
true ;
false.