program recursion

!================================================================
! Algunas funciones son "auto-referenciales" o recursivas, esto |
! es que se definen o se pueden expresar en terminos de ellas   |
! mismas:                                                       |
! F(x)=G(x,F(x)) y F(xo) = fo (corte o base de la recursion)    |
! Para algunas funiones, no es posible o es muy dificil         | 
! definirlas de forma iterativa y para ello es util la          | 
! recursion. En otros casos la situacion es la inversa. Las que |
! son por definicion recursivas, entonces la implementacion     |
! mediante una recursion es inmediata. Se debe tener cuidado    |
! la eficiencia de los recursoso de espacio y tiempo que puede  |
! requerir una inplementacion recursiva                         | 
!================================================================


integer :: n
integer :: fact
integer :: fibo

n = 5

fact = factorial(n)
print *, "factorial(n)= ",fact

call fibonacci(n,fibo)
print *,"fibonacci(n)= ",fibo


!-----------------------------------------------------------------
CONTAINS

recursive function factorial(n) result(fact) 

  integer :: fact

  if ( n == 0) then
     fact = 1
  else
     fact=n*factorial(n-1)
  end if

end function factorial

!----------------------------

recursive subroutine fibonacci(n,fib)

integer,intent(in) :: n
integer :: fib,fib1,fib2

if ( n==0 ) then
   fib = 0
else 
  if( n==1 ) then
     fib = 1
  else
     call fibonacci(n-1,fib1)
     call fibonacci(n-2,fib2)
     fib = fib1+fib2
  endif
endif 
end subroutine fibonacci


end program recursion