0

これが私の述語で、フィボナッチの数が多いかどうかを確認する必要がNありますNthFib

算術演算は関数エラーではありません。

K - current iteration
N - Nth number
Tmp - previous Fibonacci number
Ans - current Fibonacci number

フィボナッチ数列:1、1、2、3、5、8、13、21など(前の2つの合計=現在)

fib(N, NthFib) :-
    fib(1, N, 1, 0, NthFib).

fib(K, N, Ans, Tmp, NthFib) :-
    % true if Ans is NthFib, false otherwise
    ( K > N -> Ans is NthFib
    ; K =< N -> fib( K + 1, N, Ans + Tmp, Ans, NthFib)
    ).
4

3 に答える 3

2

まず、元のコードを次のように書き直します

fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).

fib(K, N, Ans, Tmp, NthFib) :- 
  K > N -> Ans = NthFib;       % use = instead of is here
  K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).

今、

?- fib(7,X).

X = 1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0))+ (1+0+1+ (1+0)+ (1+0+1))+ 
       (1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0))) 

Yes
?- fib(7,X), Z is X.

X = 1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0))+ (1+0+1+ (1+0)+ (1+0+1))+ 
       (1+0+1+ (1+0)+ (1+0+1)+ (1+0+1+ (1+0)))
Z = 21 

を参照してください。プロローグでは、データはシンボリックであり、を使用するとis、算術式が算術値に強制されます(意味のある算術式であると仮定して式を評価します)。

20が7番目のフィボナッチ数であるかどうかを確認するには、引数を評価する算術比較演算子を使用できます。

?- fib(7,X), X =:= 20.

No

つまり、コードを次のように書き直す必要があります。

fib(N, NthFib) :- fib(1, N, 1, 0, NthFib).

fib(K, N, Ans, Tmp, NthFib) :- 
  K > N -> NthFib is Ans ;       % exchange the order of operands
  K =< N -> fib((K+1), N, (Ans+Tmp), Ans, NthFib).

これで、意図したとおりに機能します。

?- fib(7,21).

Yes
?- fib(7,20).

No

ただし、これらの長い式をすべてシンボリックデータとして持ち運ぶため、効率的に機能しません。本当に必要なのは数字だけなので、他の回答で示されているように、それisを達成するために使用されます。持っているすべてのシンボリック部分式は、それを囲む式から取り出し、のis代わりに使用して名前を付け=ます。

ところで、21は実際にはシーケンスの8番目のメンバーです。コードを修正してください。

于 2012-05-25T07:37:18.490 に答える
1

で統合されている場合Kは、ではなく1K + 1で統合されます。1 + 12

于 2012-05-20T22:28:41.987 に答える
-1

私はアルゴリズムを書き直しました、それは今より単純で効率的です:

fib(0, 0).
fib(1, 1).
fib(N, F) :-
    N > 0,
    X is N - 2,
    Y is N - 1,
    fib(X, A),
    fib(Y, B),
    F is A + B.
于 2012-05-21T10:29:50.303 に答える