Prolog:减少参数中的变量

时间:2011-08-25 20:24:36

标签: prolog fibonacci

我是Prolog的新手,其任务是Fibonnaci谓词fib(N,F),其中N是序列中的数字,F是该值。我想出的不起作用,但我找到的解决方案似乎与我相同......我无法理解其中的差异。

我的版本:

/* MY VERSION, DOES NOT WORK */
fib( 0, 0).
fib( 1, 1).
fib(N,F) :-
    N > 1,
    fib(N-1,F1),
    fib(N-2,F2),
    plus(F1,F2,F).

工作版本:

/* FOUND SOLUTION, DOES WORK */
fib( 0, 0).
fib( 1, 1).
fib(N,F) :-
    N > 1,
    N1 is N-1,
    N2 is N-2,
    fib(N1,F1),
    fib(N2,F2),
    plus(F1,F2,F).

显然这个问题与我使用“N-1”和“N-2”作为参数有关,而不是先将这些值分配给新变量。但是我没有得到它...因为在其他递归的Prolog代码中,我已经成功完成了(在参数槽中减少了一个变量)。这有意义吗?

谢谢!


以下是“N-1”确实有效的例子。

line( N, _, _) :-
    N =:= 0.

line( N, M, Char) :-
    N > 0,
    N mod M =\= 1,
    write( Char), write( ' '),
    line( N-1, M, Char).

line( N, M, Char) :-
    N > 0,
    N mod M =:= 1,
    write( Char), write( '\n'),
    line( N-1, M, Char).

square( N, Char) :-
    N > 0,
    line( N*N, N, Char).

新版本的fib / 2也可以使用!

/* NEW VERSION, CHANGED TRIVIAL CASES TO EVALUATE N */
fib( N, 0) :-
    N =:= 0.

fib( N, 1).
    N =:= 1.

fib(N,F) :-
    N > 1,
    fib(N-1,F1),
    fib(N-2,F2),
    plus(F1,F2,F).

2 个答案:

答案 0 :(得分:5)

在prolog中,

1 - 2

实际上没有做任何算术(我知道,对吧?),它会创建一个结构:

-(1, 2)

is是一个评估该结构的谓词:

is(X, -(1, 2))

-1统一X.

显然,< and > (and those like it)is类似,因为它们会评估表达式。

这意味着您的fib谓词与line谓词之间存在差异

fib(0, 0).

正在使用统一,即测试术语本身是否相等:

foo(0).

?- foo(1 - 1).
false

而像=:=这样的测试测试数值相等:

foo(X) :- X =:= 0.

?- foo(1 - 1).
yes

答案 1 :(得分:0)

我可能会写下这样的谓词。

fib/2是外部“公共”界面。 N是序列中的位置(零相对)。 F与该位置的Fibonacci序列的值统一。

fibonacci/5是完成工作的内在“核心”。

  • 第一个参数是计数器
  • 第二个参数是限制
  • 第3个/第4个参数是计算序列中下一个项目所需的滑动框架。应该注意,Fibonacci序列不需要以{1,1}开始。任何两个整数都可以。
  • 第五个参数与所需结果统一。

核心中的每个子句的工作原理如下:

  • 如果N为0,则F与'1'统一。
  • 如果N为1,则F与'1'统一。
  • 如果达到了限制,我们就完成了。将F与序列中前两个元素的总和统一起来。
  • 如果计数器小于限制,则计算序列中的下一个元素并递归,从滑动窗口中滑出最旧的值。

以下是代码:

fib( N , F ) :-
  N >= 0 ,
  fibonnaci( 0 , N , 1 , 1 , F ).

fibonacci( 0     , 0     , F , _ , F ).
fibonacci( 1     , 1     , _ , F , F ).
fibonacci( Limit , Limit , X , Y , F ) :-
  F is X + Y
  .
fibonacci( Current , Limit , X , Y , F ) :-
  Current < Limit ,
  Next is Current + 1 ,
  Z is X + Y ,
  fibonacci( Next , Limit , Y , Z , F )
  .