* Re: help an o'caml beginner
2000-07-26 17:51 help an o'caml beginner John BEPPU
@ 2000-07-27 18:47 ` Alain Frisch
2000-07-27 18:56 ` Markus Mottl
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Alain Frisch @ 2000-07-27 18:47 UTC (permalink / raw)
To: John BEPPU; +Cc: caml-list
On Wed, 26 Jul 2000, John BEPPU wrote:
> >>>
> If anyone out there could implement an O'Caml fibonacci number
> generator that doesn't make redundant calculations, I would really
> appreciate it. I just need something to study.
> >>>
(I guess there will be many answers ..)
Here is a solution:
let fibo n =
let rec aux last x i = (* x is u_i; last is u_{i-1} *)
if (i = n) then x
else aux x (x + last) (i + 1)
in
if (n = 0) then 1 else
aux 1 1 1
> I wrote a recursive Perl version that doesn't make redundant
> calculations, and I'd be interested to see how different in
> structure an O'Caml version would be.
>
> sub fib_pair {
> my $n = shift;
> my @seq;
> if ($n < 2) {
> @seq = (1, 1);
> } else {
> @seq = fib_pair($n - 1);
> @seq = ($seq[1], $seq[0] + $seq[1]);
> }
> return @seq;
> }
Well, this function is not tail-recursive (the recursive call
can't be implemented as a jump). I didn't try it, but I am pretty sure
the OCaml version will be more efficient.
--
Alain Frisch
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-26 17:51 help an o'caml beginner John BEPPU
2000-07-27 18:47 ` Alain Frisch
@ 2000-07-27 18:56 ` Markus Mottl
2000-07-29 17:03 ` John BEPPU
2000-07-31 7:11 ` Vitaly Lugovsky
2000-07-27 18:57 ` help an o'caml beginner Remi VANICAT
` (3 subsequent siblings)
5 siblings, 2 replies; 12+ messages in thread
From: Markus Mottl @ 2000-07-27 18:56 UTC (permalink / raw)
To: John BEPPU; +Cc: caml-list
On Wed, 26 Jul 2000, John BEPPU wrote:
> If anyone out there could implement an O'Caml fibonacci number
> generator that doesn't make redundant calculations, I would really
> appreciate it. I just need something to study.
Here a collection of three fibonacci algorithms. The first one is the
"simple-minded" one, the second uses tail-recursion, which removes some
redundant computations, too. The third one - well, try it out ;-)
---------------------------------------------------------------------------
let rec fib1 = function
| n when n <= 1 -> 1
| n -> fib1 (n-1) + fib1 (n-2)
let fib2 n =
let rec fib2_aux n2 n1 = function
| m when m = n -> n1
| m -> fib2_aux n1 (n2+n1) (m+1) in
if n <= 1 then 1 else fib2_aux 1 2 2
let rec fib3_aux = function
| 0 -> 1, 0
| 1 -> 0, 1
| n ->
let k = n/2 in
let a, b = fib3_aux k in
let aa = a*a and bb = b*b and ab2 = 2*a*b in
let ab2bb = ab2 + bb in
if 2*k = n then aa + bb, ab2bb
else ab2bb, ab2bb + aa + bb
let fib3 n =
if n <= 1 then 1
else
let k = n/2 in
let a, b = fib3_aux k in
let ab = a + b in
if 2*k = n then ab*ab + b*b
else ab*ab + 2*b*ab
let _ = Printf.printf "%d\n" (fib3 1000000)
---------------------------------------------------------------------------
Btw., algorithms 2 + 3 can both be generated by automatic program
transformation. If you want to learn more about this, read:
@Article{Pettorossi-Proietti96,
key = "Pettorossi \& Proietti",
author = "Alberto Pettorossi and Maurizio Proietti",
title = "Rules and Strategies for Transforming Functional and
Logic Programs",
journal = "ACMCS",
volume = "28",
number = "2",
pages = "360--414",
month = jun,
year = "1996",
annote = "Many references.",
}
Best regards,
Markus Mottl
--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-27 18:56 ` Markus Mottl
@ 2000-07-29 17:03 ` John BEPPU
2000-07-29 17:23 ` Markus Mottl
2000-07-31 7:11 ` Vitaly Lugovsky
1 sibling, 1 reply; 12+ messages in thread
From: John BEPPU @ 2000-07-29 17:03 UTC (permalink / raw)
To: caml-list; +Cc: Markus Mottl
[ date ] 2000/07/27 | Thursday | 08:56 PM
[ author ] Markus Mottl <mottl@miss.wu-wien.ac.at>
> let rec fib3_aux = function
> | 0 -> 1, 0
> | 1 -> 0, 1
> | n ->
> let k = n/2 in
> let a, b = fib3_aux k in
> let aa = a*a and bb = b*b and ab2 = 2*a*b in
> let ab2bb = ab2 + bb in
> if 2*k = n then aa + bb, ab2bb
> else ab2bb, ab2bb + aa + bb
>
> let fib3 n =
> if n <= 1 then 1
> else
> let k = n/2 in
> let a, b = fib3_aux k in
> let ab = a + b in
> if 2*k = n then ab*ab + b*b
> else ab*ab + 2*b*ab
>
> let _ = Printf.printf "%d\n" (fib3 1000000)
This one was faster than the C version I posted.
The others were pretty close, too. I continue to
be impressed. I have a hard time believing fib3
was created by a mechanical transformation... it
doesn't look anything like the other implementations.
I mean, I believe you as a matter of good faith, but
I'm amazed.
<question type="stupid">
What does the keyword "in" mean?
</question>
> Btw., algorithms 2 + 3 can both be generated by automatic program
> transformation. If you want to learn more about this, read:
[snipped the reference...]
Thanks for the article... I'll hit up the local universities,
and see if I can't track it down.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-29 17:03 ` John BEPPU
@ 2000-07-29 17:23 ` Markus Mottl
0 siblings, 0 replies; 12+ messages in thread
From: Markus Mottl @ 2000-07-29 17:23 UTC (permalink / raw)
To: John BEPPU; +Cc: caml-list
On Sat, 29 Jul 2000, John BEPPU wrote:
> This one was faster than the C version I posted.
It should be, because it computes the fibonacci function in logarithmic
time, whereas the "usual" function does it in linear time (fib2). The
"simple" fibonacci implementation (fib1) is even worse: exponential time.
> The others were pretty close, too. I continue to
> be impressed. I have a hard time believing fib3
> was created by a mechanical transformation... it
> doesn't look anything like the other implementations.
> I mean, I believe you as a matter of good faith, but
> I'm amazed.
No, the OCaml-code was not generated by automated transformations, but the
techniques are known and presented in the reference I mentioned - I just
took their "transformed" solution and translated it to OCaml. But it is
principally possible to apply such transformation techniques to functional
languages in general, because of their nice mathematical properties.
Since implementing such transformation systems correctly is a fairly
difficult task, there are not yet many around, and those that exist
normally operate on simplified languages to make life for researchers
easier...
> <question type="stupid">
> What does the keyword "in" mean?
> </question>
It is just a keyword to prevent ambiguities when writing expressions. E.g.:
let x = y z ...
is not the same as
let x = y in
z ...
Best regards,
Markus Mottl
--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-27 18:56 ` Markus Mottl
2000-07-29 17:03 ` John BEPPU
@ 2000-07-31 7:11 ` Vitaly Lugovsky
2000-07-31 8:43 ` Markus Mottl
2000-08-02 16:58 ` Printable Caml manual Walid Taha
1 sibling, 2 replies; 12+ messages in thread
From: Vitaly Lugovsky @ 2000-07-31 7:11 UTC (permalink / raw)
To: Markus Mottl; +Cc: John BEPPU, caml-list
On Thu, 27 Jul 2000, Markus Mottl wrote:
> Btw., algorithms 2 + 3 can both be generated by automatic program
> transformation. If you want to learn more about this, read:
>
> @Article{Pettorossi-Proietti96,
Can this article be found on a WEB?
--
V.S.Lugovsky aka Mauhuur (http://ontil.ihep.su/~vsl) (UIN=45482254)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-31 7:11 ` Vitaly Lugovsky
@ 2000-07-31 8:43 ` Markus Mottl
2000-08-02 16:58 ` Printable Caml manual Walid Taha
1 sibling, 0 replies; 12+ messages in thread
From: Markus Mottl @ 2000-07-31 8:43 UTC (permalink / raw)
To: Vitaly Lugovsky; +Cc: John BEPPU, caml-list
On Mon, 31 Jul 2000, Vitaly Lugovsky wrote:
> > @Article{Pettorossi-Proietti96,
>
> Can this article be found on a WEB?
Yes, it can:
http://www.iasi.rm.cnr.it/~proietti/reports.html
Grab technical report 423 there: this is a nice overview of the topic...
Best regards,
Markus Mottl
--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
^ permalink raw reply [flat|nested] 12+ messages in thread
* Printable Caml manual
2000-07-31 7:11 ` Vitaly Lugovsky
2000-07-31 8:43 ` Markus Mottl
@ 2000-08-02 16:58 ` Walid Taha
1 sibling, 0 replies; 12+ messages in thread
From: Walid Taha @ 2000-08-02 16:58 UTC (permalink / raw)
To: caml-list
Dear collegues,
I am writing an article about imperative programming, and would like to
use Caml for examples. It's been a bit hard to work from the manuals on
the web (partly because the network keeps doing fishy things). I would
really appreciate it if you could point me to a comprehensive manual that
covers things like IO, and which I can also easily print and put on my
desk (i.e., something in .ps or .dvi format, for example).
Also, I would certainly appreciate your input on the first draft when it
is ready, so let me know if you are interesting in a taking a look.
Many thanks in advance,
Walid.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-26 17:51 help an o'caml beginner John BEPPU
2000-07-27 18:47 ` Alain Frisch
2000-07-27 18:56 ` Markus Mottl
@ 2000-07-27 18:57 ` Remi VANICAT
2000-07-27 19:08 ` Jean-Christophe Filliatre
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Remi VANICAT @ 2000-07-27 18:57 UTC (permalink / raw)
To: caml-list
John BEPPU <beppu@lineo.com> writes:
> Hi.
>
[...]
> This was much faster than any of the recursive versions, because it
> doesn't have to recompute the same values over and over again.
>
> Next, I tried to fumble my way through making an O'Caml version of
> this iterative algorithm, but I failed due to my lack of knowledge
> about this language. (I hesitate to print the tutorial, because
> that's a lot of paper -- I wish the tutorial were available in HTML.
> I just may have to print it, though.)
>
>
> >>>
> If anyone out there could implement an O'Caml fibonacci number
> generator that doesn't make redundant calculations, I would really
> appreciate it. I just need something to study.
> >>>
>
it easy : you have to use an auxiliary function :
let fib n =
let rec aux n n1 n2 =
if n <= 2 then (n1 + n2)
else aux (n - 1) (n1 + n2) n1 in
if (n < 3) then 1 else aux (n - 1) 1 1
(an exact translation of your c function would be :
let fib n =
if (n < 2) then n
else
let rec aux i val n1 n2 =
if i < n then val
else aux (i + 1) (n1 + n2) (n1 + n2) n1
the idea here is for each variable of the c function have an argument
to the recursive caml function, and, instead of changing the variable,
to call the aux function with the new value.
Then I've done some clean up and removal of unused arguments)
--
Rémi Vanicat
vanicat@labri.u-bordeaux.fr
http://dept-info.labri.u-bordeaux.fr/~vanicat
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-26 17:51 help an o'caml beginner John BEPPU
` (2 preceding siblings ...)
2000-07-27 18:57 ` help an o'caml beginner Remi VANICAT
@ 2000-07-27 19:08 ` Jean-Christophe Filliatre
2000-07-27 21:31 ` Laurent Chéno
2000-07-27 23:47 ` Michel Quercia
5 siblings, 0 replies; 12+ messages in thread
From: Jean-Christophe Filliatre @ 2000-07-27 19:08 UTC (permalink / raw)
To: John BEPPU; +Cc: caml-list
In his message of Wed July 26, 2000, John BEPPU writes:
>
> Next, I wrote an iterative C version.
> [...]
> This was much faster than any of the recursive versions, because it
> doesn't have to recompute the same values over and over again.
> [...]
> If anyone out there could implement an O'Caml fibonacci number
> generator that doesn't make redundant calculations, I would really
> appreciate it. I just need something to study.
First, you can write it exactly as in C, since ocaml supports
references and imperative programming constructs.
But there is an even more direct way of writing it, in a functional
way, which could be the following:
======================================================================
let rec fib_aux v1 v2 n =
if n = 0 then
v1
else
fib_aux v2 (v1 + v2) (pred n)
let fib n = fib_aux 0 1 n
======================================================================
(In a general way, a C loop becomes a recursive function with as many
arguments as variables involved in the loop.)
By the way, if you are interested in computing Fibonacci numbers,
there are even more efficient ways to do that. Here is a pointer (code
by Xavier Urbain, documentation in French):
http://www.lri.fr/~filliatr/pub/lucas.ps
--
Jean-Christophe Filliatre
Computer Science Laboratory Phone (650) 859-5173
SRI International FAX (650) 859-2844
333 Ravenswood Ave. email filliatr@csl.sri.com
Menlo Park, CA 94025, USA web http://www.csl.sri.com/~filliatr
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-26 17:51 help an o'caml beginner John BEPPU
` (3 preceding siblings ...)
2000-07-27 19:08 ` Jean-Christophe Filliatre
@ 2000-07-27 21:31 ` Laurent Chéno
2000-07-27 23:47 ` Michel Quercia
5 siblings, 0 replies; 12+ messages in thread
From: Laurent Chéno @ 2000-07-27 21:31 UTC (permalink / raw)
To: John BEPPU, Caml list
Le 26/07/00 à 11:51, beppu@lineo.com (John BEPPU) écrivait :
> Hi.
--- Please excuse my poor english ---
>
> Next, I wrote an iterative C version.
>
> #include <stdio.h>
>
> int fib(int n)
> {
> int val = 2;
> int n1 = 2;
> int n2 = 1;
> int i;
> if (n < 2)
> return n;
>
> for (i = 2; i < n; i++) {
> val = n2 + n1;
> n2 = n1;
> n1 = val;
> }
> return val;
> }
>
> int main(char *argc, char **argv)
> {
> printf("%d\n", fib(atoi(argv[1])));
> return 0;
> }
>
> This was much faster than any of the recursive versions, because it
> doesn't have to recompute the same values over and over again.
>
the basic translation can be for example :
let fib n =
let val = ref 2
and n1 = ref 2
and n2 = ref 1
in
if n < 2 then n
else for i = 2 to n - 1 do
val := !n1 + !n2 ;
n2 := !n1 ;
n1 := !val
done ;
!val ;;
But I prefer a recursive and efficient version like this :
let fib n =
let rec fibaux n p q =
if n = 0 then p
else fibaux (n - 1) q (p + q)
in
fibaux n 0 1 ;;
this is a terminal recursion : try it !
--
Laurent Chéno Paris (France)
<http://pauillac.inria.fr/~cheno/>
--
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: help an o'caml beginner
2000-07-26 17:51 help an o'caml beginner John BEPPU
` (4 preceding siblings ...)
2000-07-27 21:31 ` Laurent Chéno
@ 2000-07-27 23:47 ` Michel Quercia
5 siblings, 0 replies; 12+ messages in thread
From: Michel Quercia @ 2000-07-27 23:47 UTC (permalink / raw)
To: caml-list
Le Wed, 26 Jul 2000, John BEPPU a écrit :
> I tried out the recursive fibonacci number program
> ...
> Next, I tried to fumble my way through making an O'Caml version of
> this iterative algorithm, but I failed due to my lack of knowledge
> about this language.
Below are three translations of your iterative C code :
------------------------------------------------------------
(* iterative Caml code *)
let fib(n) =
let a = ref(1) and b = ref(1) in
for i=2 to n do
let x = !a + !b in
a := !b;
b := x
done;
!b
;;
-------------------------------------------------------------
(* recursive Caml code, fib2(n) returns (fib(n-1),fib(n)) *)
let rec fib2(n) =
if n <= 1 then (n,1)
else let (a,b) = fib2(n-1) in (b,a+b)
;;
let fib(n) = let (_,x) = fib2(n) in x;;
-------------------------------------------------------------
(* tail-recursive Caml code, fib3 a b n computes a*fib(n) + b*fib(n-1) *)
let rec fib3 a b n = if n <= 1 then a + b*n else fib3 (a+b) a (n-1);;
let fib(n) = fib3 1 0 n;;
--------------------------------------------------------
Note that there are also divide-and-conquer algorithms for computing Fibonacci
numbers that achieve logarithmic computing time with respect to the input.
> I wish the tutorial were available in HTML.
There is atutorial included in the html documentation.
Regards,
--
Michel Quercia
23 rue de Montchapet, 21000 Dijon
http://pauillac.inria.fr/~quercia
mailto:quercia@cal.enst.fr
^ permalink raw reply [flat|nested] 12+ messages in thread