🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.functional
6 messages
6 total messages Started by Ulrich Neumerkel E185/1 +4315880... Tue, 10 Nov 1992 16:44
Is efficient backtracking feasible in functional languages?
#561
Author: Ulrich Neumerkel E185/1 +4315880...
Date: Tue, 10 Nov 1992 16:44
36 lines
2355 bytes
In many textbooks and papers about functional languages it is suggested
that lazy evaluation allows to implement backtracking by representing
the sequence of solutions by an appropriate datastructure which is
generated in a lazy manner. Is seems however, that such an encoding,
although conceptually elegant, requires space proportional to the
number of choices already considered.

Below is such a backtracking program `strangesucc' that computes the
successor of a number by searching through all natural numbers and
selecting the first solution found. This program here is a little
overkill. It serves only as an example for the problems I
encountered in more complex backtracking programs. Take a more
complex condition and the program does make sense.

strangesucc n =	hd [x|x<-[0..];x>n];

This program should run in constant space and linear time [1].
However, for the implementations I tried, it turns out that the program
seems to run in linear space! For a small n as 10000 the program aborts
due to memory problems. Also a rewriting of the program to encode list comprehensions explicitly did not yield the desired result.

Is there ANY implementation of a lazy functional language to execute
the program above in an efficient manner (i.e. in constant space)?

Thank You, Ulrich

[1] more precicely in log n space and n log n time, if we consider
numbers of arbitrary magnitude.

PS: Note that backtracking as implemented in Prolog does not have
such problems.
-- 
Ulrich Neumerkel, ulrich@dec4.wu-wien.ac.at ulrich@mips.complang.tuwien.ac.at
TU-Wien, Vienna University of Technology, +431 58801 4477 fax +431 5057838
Institut fuer Computersprachen E185/1 Argentinierstr.8/4, A-1040 Wien Austria
Re: Is efficient backtracking feasible in functional languages?
#564
Author: Thomas M. Breuel
Date: Wed, 11 Nov 1992 10:41
45 lines
2515 bytes
In article <1992Nov10.164456.18062@email.tuwien.ac.at> ulrich@mips.complang.tuwien.ac.at (Ulrich Neumerkel E185/1 +43158801/4477) writes:

   In many textbooks and papers about functional languages it is suggested
   that lazy evaluation allows to implement backtracking by representing
   the sequence of solutions by an appropriate datastructure which is
   generated in a lazy manner. Is seems however, that such an encoding,
   although conceptually elegant, requires space proportional to the
   number of choices already considered.

   [...]

   strangesucc n =	hd [x|x<-[0..];x>n];

   This program should run in constant space and linear time [1].
   However, for the implementations I tried, it turns out that the program
   seems to run in linear space! For a small n as 10000 the program aborts
   due to memory problems. Also a rewriting of the program to encode list
   comprehensions explicitly did not yield the desired result.

   Is there ANY implementation of a lazy functional language to execute
   the program above in an efficient manner (i.e. in constant space)?

There should be no problem with that in principle. For example, the
following program, using a lazy streams library in SML, only requires
constant space (3397288 bytes). Of course, it garbage collects a
lot...

  - Stream.head(Stream.filter(fn x => x > 1000000,Stream.iota()));
  
  [Major collection... 21% used (3397260/15733684), 1920 msec]
  
  [Major collection... 21% used (3397288/15730836), 1910 msec]
  
  [Major collection... 21% used (3397288/15730948), 1920 msec]
  
  [Major collection... 21% used (3397288/15730888), 1920 msec]
  
  [Major collection... 21% used (3397288/15730888), 1910 msec]
  val it = 1000001 : int
  -

In general, I think that backtracking is better expressed using
callcc; is there some equivalent to callcc in lazy languages?

					Thomas.
Re: Is efficient backtracking feasible in functional languages?
#566
Author: Joe Armstrong
Date: Wed, 11 Nov 1992 17:17
29 lines
1307 bytes
|> 
|>    strangesucc n =	hd [x|x<-[0..];x>n];
|> 
	....
|> 
|>   - Stream.head(Stream.filter(fn x => x > 1000000,Stream.iota()));
|>   
|>   [Major collection... 21% used (3397260/15733684), 1920 msec]
|>   
|>   [Major collection... 21% used (3397288/15730836), 1910 msec]
|>   
|>   [Major collection... 21% used (3397288/15730948), 1920 msec]
|>   
|>   [Major collection... 21% used (3397288/15730888), 1920 msec]
|>   
|>   [Major collection... 21% used (3397288/15730888), 1910 msec]
|>   val it = 1000001 : int
|>   -

	Wonderfull  !!

	This is the kind of stuff that gives FP a bad name :-)

	Is their a transformation system which can prove that

	strangesucc x == x + 1 ?

	Joe
Re: Is efficient backtracking feasible in functional languages?
#570
Author: Bj|rn Lisper
Date: Thu, 12 Nov 1992 13:53
33 lines
2207 bytes
In article <1992Nov11.171742.18783@eua.ericsson.se> joe@erix.ericsson.se
(Joe Armstrong) writes:
>|> 
>|>    strangesucc n =	hd [x|x<-[0..];x>n];
>|> 
	   ....

>	Wonderfull  !!
>	This is the kind of stuff that gives FP a bad name :-)
>	Is their a transformation system which can prove that
>	strangesucc x == x + 1 ?

Was strangesucc a function from natural numbers or integers? In the latter
case "strangesucc x == x + 1" is false for x < 0. For natural numbers, quite
intricate knowledge about them is required to prove the equality: we must
know that n+1 is the least natural number such that n < n+1, for instance,
we must know that this number will, for all n, eventually show up in the
list defined by [x|x<-[0..]], and we must know that it is the first such
number that shows up. The latter two facts must be proved by induction, I
think, ultimately using the Peano axioms for natural numbers. The proof also
implies a proof of termination for the function. So, my answer is "not
without theorem proving capabilities".

A more general data flow analysis should, however, at least be able to find
that at most two elements in the list [x|x<-[0..]] need to be stored
simultaneously. This is since only one element is returned, every element in
the list can be computed using only the previous element, and the
termination test involves only the element to be returned and the argument
to the function. So a smart compiler should throw away the "internal" list
[x|x<-[0..]] completely and allocate two registers instead.  Apparently
compilers today aren't that smart.

Bjorn Lisper
Re: Is efficient backtracking feasible in functional languages?
#571
Author: R.E.Jones
Date: Thu, 12 Nov 1992 14:47
40 lines
2461 bytes
In article <1992Nov10.164456.18062@email.tuwien.ac.at> ulrich@mips.complang.tuwien.ac.at writes:
>
>strangesucc n =	hd [x|x<-[0..];x>n];
>
>This program should run in constant space and linear time [1].
>However, for the implementations I tried, it turns out that the program
>seems to run in linear space! For a small n as 10000 the program aborts
>due to memory problems. Also a rewriting of the program to encode list comprehensions explicitly did not yield the desired result.
>
>Is there ANY implementation of a lazy functional language to execute
>the program above in an efficient manner (i.e. in constant space)?
>-- 
>Ulrich Neumerkel, ulrich@dec4.wu-wien.ac.at ulrich@mips.complang.tuwien.ac.at
>TU-Wien, Vienna University of Technology, +431 58801 4477 fax +431 5057838
>Institut fuer Computersprachen E185/1 Argentinierstr.8/4, A-1040 Wien Austria


I've tried this on an implementation based on the G-machine. My machine
uses the blackholing technique to avoid space leaks that I describe in [1].
I translate list comprehensions to their equivalent using foldr, map and
concat; for example see [2].
I have no problem with this function: it runs in constant space (262 words
of heap space if you want to compare figures with those give in [1]).

[1] Richard E. Jones. `Tail recursion without space leaks', Journal of 
    Functional Programming 2(1), 73--79, January 1992.
    
[2] Richard Bird & Phil Wadler. `Introduction to Functional Programming', 
    Prentice Hall, 1988. Page 63.


Richard Jones

===============================================================================

Computing Laboratory				email: rej@ukc.ac.uk
University of Kent at Canterbury		Telephone: 0227 764000 ext.7550
Canterbury, CT2 7NF, U.K.			FAX: 0227 762811

===============================================================================
Re: Is efficient backtracking feasible in functional languages?
#575
Author: John van Groningen
Date: Thu, 12 Nov 1992 17:03
41 lines
1748 bytes
In article <1992Nov10.164456.18062@email.tuwien.ac.at> Ulrich Neumerkel
E185/1 +43158801/4477, ulrich@mips.complang.tuwien.ac.at writes:

>strangesucc n =	hd [x|x<-[0..];x>n];
>
>This program should run in constant space and linear time [1].
>However, for the implementations I tried, it turns out that the program
>seems to run in linear space! For a small n as 10000 the program aborts
>due to memory problems. Also a rewriting of the program to encode list 
>comprehensions explicitly did not yield the desired result.

The following rewrite yields the desired result in constant space
in Haskell B:

main = print (h::Integer)

hd (e:l) = e

g n = n : g (n+1)

f [] n = []
f (x:v) n = if (x>n)
               then (x:f v n)
               else (f v n)

h :: Integer
h = hd (f (g 0) 1000000)

But if you change the function 'main' to:

main = print (hd (f (g 0) 1000000)::Integer)

the program runs in linear space !

>Is there ANY implementation of a lazy functional language to execute
>the program above in an efficient manner (i.e. in constant space)?

Yes, Chalmers LML implementation.


                         John van Groningen
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads