Prolog中的斐波纳契 - 假如果错误

时间:2017-11-07 13:30:04

标签: prolog fibonacci

我有一个程序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/来运行我的程序查询。

1 个答案:

答案 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/1R或更低,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

现在我们可以:

  1. 枚举所有索引和相应的斐波纳契数:

    :- 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).
  2. 获取 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
    ...
    
  3. 获取相应斐波纳契数为特定值的 i

    ?- fib(2,B).
    B = 2 ;
    false.
    
    ?- fib(10,B).
    B = 89 ;
    false.
    
  4. 检查 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.