我有一个程序fib(X,Y)。如果Y是第X个Fibonacci数,则返回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.
我做错了什么?我正在使用https://swish.swi-prolog.org/来运行我的程序查询。
答案 0 :(得分:3)
这里的问题是您写了两个子句$("#GetNewsletter").change(function () {
var checked = $(this).prop("checked");
if (checked) {
$('#Email').rules('add', { //set required rule
required: true,
messages: {
required: "Email is required."
}
});
}
else {
$('#Email').rules('remove', 'required'); //remove rule and call valid()
$('#Email').valid();
}
});
和fib(X, Y, 0, V) :-
。 Prolog使用回溯:如果已经尝试了一个子句,它将会 - 无论是成功还是失败 - 以后再重试下一个子句(有一些元谓词如fib(X, Y, R, V) :-
可以改变这一点)。
因此即使once/1
为R
或更低,Prolog也会尝试第二个条款。
解决这个问题的一个快速方法是使用第二个句子的守卫:
0
此外,您的代码不是很优雅,因为您不能以相反的方式使用关系,也不能查询 X -th元素。
例如,您使用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).
,但这会阻止统一:如果我们想知道 X -th斐波纳契数,我们想要一种方法来传播结果。所以我们可以改为使用统一:
Y == V
但是现在我们仍然没有双向关系:我们无法获得给定值 V 的 X 。这更复杂。最简单的方法可能就是使用fib(_, V, 0, V).
fib(X, Y, R, V) :-
R > 0,
Z is X + Y,
C is R - 1,
fib(Y, Z, C, V).
:
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).
获取 i -th斐波纳契数:
?- fib(A,B).
A = 0,
B = 1 ;
A = B, B = 2 ;
A = B, B = 3 ;
A = 4,
B = 5 ;
A = 5,
B = 8 ;
A = 6,
B = 13 ;
A = 7,
B = 21
...
获取相应斐波纳契数为特定值的 i :
?- fib(2,B).
B = 2 ;
false.
?- fib(10,B).
B = 89 ;
false.
检查 i -th Fibonacci数是否为给定值:
?- 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.