[comp.lang.misc] Array references cannot be made optimal

misha@ai.mit.edu (Mike Bolotski) (11/13/90)

In article <23904:Nov905:22:5290@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
|> In article <MISHA.90Nov7191750@just-right.ai.mit.edu> I write:
|> > In article <7659:Nov620:58:5990@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
|> > > pointers (arrays) are pre-indexed appropriately. Could one of you CS
|> > > types please illustrate to Jim that finding optimal addition chains in a
|> > > general computation is equivalent to solving the halting problem?
|> > Bzzt.  But thanks for playing, Dan.
|> > Optimal addition is NP.
|> 
|> Bzzt. But thanks for playing, Mike.
|> 
|> Finding optimal addition chains in a general computation is most
|> certainly equivalent to the halting problem. Since no CS types have
|> stepped forward, I'll illustrate.

Consulting that a standard reference text in the field, "Compilers:
Principles, Techniques and Tools", by Aho, Sethi, and Ullman 
reveals the following on page 517.

"Finding an optimal assignment of registers to variables is difficult,
 even with single-register values. Mathematically, the problem is
 NP-complete."

Now this is register assignment, not evaluation order, but Dan's 
"outline of proof"  switched the problem to allocation of address
register.  But not to despair:

"The order in which computations are performed can affect the 
 efficiency of the target code. [..] Picking a best order is
 another difficult, NP-complete problem." (p 518).

|> Outline of proof: Take a program. Add an array[2], x. Read x[0] and x[1]
|> from the outside. Use x[0]. In a subroutine, use x[1] repeatedly and
|> then exit. Replace every exit with a call to the subroutine.
|> 
|> Now if the program does not exit, it is best to keep &x[1] around. If
|> the program exits, it is best to keep only &x[0] around. Q.E.D.

The above is not a proof. It is not even close to a proof. In fact,
I suspect you have the common misconception that the halting problem
consists of determining whether a particular program will ever halt
or not.  I suggest you consult a standard theory of computation 
text, such as Hopcroft and Ullman for a definition, and examine
what a proof by reduction to a Ktm looks like.

[ Timer description deleted due to irrelevance ].

|> Q.E.D.

Right.

|> Indeed. (As a matter of fact, it's quite feasible to solve the halting
|> problem in practice---the algorithm just depends on the program.)

If this statement was made with full knowledge of what the halting
problem is, it would have been a wonderful .sig quote. 


Excerpted from another article by Dan, replying to Jim Giles:

|> I simply don't understand where you and Mike are getting this ridiculous
|> assertions from. What problems are you fantasizing you've solved here?
|> Where are your purported proofs?

The louder you yell your mistakes, Dan, the more embarassing they become.
Especially since you are venturing out of the safe realm of opinion and 
dealing with facts that can be proven mathematically. 

-- 
Mike Bolotski          Artificial Intelligence Laboratory, MIT
misha@ai.mit.edu       Cambridge, MA

Okay, just this once: 

"It's quite feasible to solve the halting problem in practice."
  -- Dan Bernstein 

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/14/90)

There does not exist an algorithm that will convert an (optimal) array
program into its optimal pointer form. That summarizes what I've said so
far in this thread.

What does it mean for real languages? It means that the programmer
*must* be allowed to look at an array x from the vantage point of x[a],
rather than x[0]. This array shifting doesn't have to look like C's
pointer arithmetic, even if it is implemented that way in machine
language, and even if it's doing no more than providing pointer
arithmetic with a different syntax. It just has to be there.

Once you have array shifting, finding the optimal pointer form is rather
easy, as Jim has been saying. I don't know of any efficiency advantages
of pointers in that case.

In article <11839@life.ai.mit.edu> misha@ai.mit.edu writes:
> "Finding an optimal assignment of registers to variables is difficult,
>  even with single-register values. Mathematically, the problem is
>  NP-complete."

I am not talking about finding an optimal assignment of registers to
variables, so even if I were to blindly believe this statement, I'd
stick to my position.

> "The order in which computations are performed can affect the 
>  efficiency of the target code. [..] Picking a best order is
>  another difficult, NP-complete problem." (p 518).

See above. Don't fall into the trap of misinterpreting AHU's statement.
Only a very limited class of optimizations may be performed by computer.
The general problem of finding the best way to compute something isn't
just NP: it's undecidable.

An example of a decidable problem: Find the fastest way to compute x^n,
for a single exponent n. This is the simple addition chain problem.

An example of a problem not yet proven either decidable or undecidable:
Find the optimal way to compute x^n, for a given range of exponents n,
under a certain computational model, where ``optimal'' means optimal in
a weighted average of run time and program space. It's highly likely
that a computer can't solve this, but you never know.

If you see the difference between these two problems, you'll appreciate
what AHU are saying.

> |> Outline of proof:
     [ ... ]
> The above is not a proof. It is not even close to a proof.

How observant you are. I called it an ``outline'' for a reason. In the
article before this, I went through an informal proof.

> In fact,
> I suspect you have the common misconception that the halting problem
> consists of determining whether a particular program will ever halt
> or not.

In fact, I suspect you have not been on the net long enough to know any
better. Or were you not reading comp.theory in January 1989? See my next
article. 

> [ Timer description deleted due to irrelevance ].
> |> Q.E.D.
> Right.

I'm disgusted by your lack of appreciation for the value of constructive
criticism in modern science.

If you see something I've missed, point to it! (Or index it! :-) )
I just don't see how you plan to figure out whether you should keep a
pointer to x[0] and use that to get x[1], or whether the opposite order
is better.

> |> Indeed. (As a matter of fact, it's quite feasible to solve the halting
> |> problem in practice---the algorithm just depends on the program.)
> If this statement was made with full knowledge of what the halting
> problem is, it would have been a wonderful .sig quote. 

Feel free to put it in your .sig---after you understand what I say in my
next article.

> |> I simply don't understand where you and Mike are getting this ridiculous
> |> assertions from. What problems are you fantasizing you've solved here?
> |> Where are your purported proofs?
> The louder you yell your mistakes, Dan, the more embarassing they become.

But you haven't pointed out a single mistake!

*You* just implied that it is not feasible to solve the halting problem
in practice. As anyone who reads my next article will realize, you are
wrong.

There. I've now pointed out an error (or at least implied error) of
yours. Can you make the effort to follow the same format if you really
do see a mistake in what I post? Or are my suspicions correct, and you
haven't, in fact, seen any error?

> Especially since you are venturing out of the safe realm of opinion and 
> dealing with facts that can be proven mathematically. 

No shit. That's one of the things that you learn to do when you're
trained as a mathematician.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/14/90)

Here are two articles about the practical solution to the halting
problem. The first, from February this year, is short and should give
people an idea of the resources implied by ``practical solution.''
(Practical enough that it could reasonably be an option in Saber-C.)

The second, from January 1989, was my first posting of the solution, on
comp.theory. I remember having just finished reading an article in good
old Dr. Dobbs about the halting problem. It gave the usual presentation
of the theory, but went out on a limb and said that the halting problem
wasn't solvable in practice. As happens so often in computer `science,'
the limb wasn't connected to the tree's trunk. After seeing a similarly
unjustified statement in a discussion in comp.lang.c and comp.theory, I
was sufficiently annoyed to write the article.

Several months ago someone from England seemed interested in
implementing the method. I don't know what's come of it. Oh, well.

---Dan

>From: brnstnd@stealth.acf.nyu.edu
Newsgroups: comp.software-eng
Subject: Re: Have *YOU* ever written a program which COULDN'T be proven correct?
Message-ID: <3803:04:53:29@stealth.acf.nyu.edu>
Date: 14 Feb 90 04:53:30 GMT
Distribution: usa

In article <793@arc.UUCP> steve@arc.UUCP (Steve Savitzky) writes:
> I think you missed my point, which is that whether or not the halting
> problem can be solved *in theory* for real programs on real computers,
> it cannot be solved *in practice*.  

A year ago I posted a short note to comp.theory titled Finite Halting
Problem Considered Solvable. The gist of it is that you can solve the
halting problem for a program using just twice the memory and thrice
the time.

In practice, with language support, you designate certain variables
to be tested for looping. Those variables are stored twice, and the
program runs at a third of the speed. If those variables together enter
a loop, the loop will be detected during its first period. For some
programs this could be very useful.

---Dan

>From: bernsten@phoenix.UUCP (Dan Bernstein)
Newsgroups: comp.theory
Subject: Finite Halting Problem Considered Solvable
Message-ID: <8901162049.AA11027@jade.berkeley.edu>
Date: 16 Jan 89 16:32:35 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Reply-To: TheoryNet List <THEORYNT%NDSUVM1.bitnet@jade.berkeley.edu>,
        Dan Bernstein <phoenix!bernsten@PRINCETON.EDU>
Distribution: inet
Organization: The Internet
Lines: 52


The halting problem is to determine whether a given program loops forever.
This is an uncomputable function of a program, as we all know.

But if a program is restricted to a finite number of states then the
problem is computable. The practical solution is that we run the program
on two machines with that number of states, one machine exactly twice as
fast as the other; if the program loops in time t to t+u, then we will
see the machines in exactly the same state at time 3t to 3t+3u.

Now consider modern, real computers.

The space needed for this is practical. But the time is a trickier
consideration. How do we compare the states of two computers? The
solution is that in unit time a computer modifies a bounded-size
portion of its state as expressed in bits. So we merely watch what
registers, memory bytes, etc. are changed, incrementing a difference
count when something is made different on the two machines and
decrementing it when something is made the same. As a matter of fact,
this (at least for memory) is already done by good caches. It would
be a simple modification to those caches designed for multiprocessors
to have them keep track of (1) registers and flags as well as memory
and (2) a difference count.

Of course, this eminently practical hardware solution is only
appropriate if the entire machine is involved in a single computation
that we don't want to have accidentally looping. But I'd say that
the problem is practically solvable in software for many situations.

For example, MACSYMA and similar programs could have a feature that
a user-defined function be run three times slower and have it detect
infinite loops of variables blah, blah, and blah in the function. I
would expect that this be restricted to non-recursively written functions,
and restricted to functions that don't use non-mathematical stuff like
reading from a disk file---but it's still quite doable and would be a
real, live, practical solution to the halting problem.

More ambitiously, I can see how a C compiler could compile a function to
detect infinite loops. The function would probably run somewhat slower
than just three times, as most optimizations would go down the drain and
dealing with the difference count would be a major speed factor relative
to the speed of single expressions. And yes, it would take double the
memory---which could be a problem if the function had an array taking
an amount of space comparable to the space available on the machine.
And I would expect the restriction that the function and everything it
calls must use only built-in C, no system calls or anything else possibly
external; and also that the function and everything it calls must only
use variables local to themselves. But after all these caveats this still
remains a valuable tool that I would have loved to have for testing many
programs: the practical solution to the halting problem.

---Dan Bernstein, bernsten@phoenix.princeton.edu

christer@cs.umu.se (Christer Ericson) (11/14/90)

In article <3975:Nov1323:25:4390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>Here are two articles about the practical solution to the halting
>problem. The first, from February this year, is short and should give
>people an idea of the resources implied by ``practical solution.''
>(Practical enough that it could reasonably be an option in Saber-C.)
>
> [lots of stuff deleted]
>
>The halting problem is to determine whether a given program loops forever.
>This is an uncomputable function of a program, as we all know.
>
>But if a program is restricted to a finite number of states then the
>problem is computable. The practical solution is that we run the program
>on two machines with that number of states, one machine exactly twice as
>fast as the other; if the program loops in time t to t+u, then we will
>see the machines in exactly the same state at time 3t to 3t+3u.
>
> [even more deleted stuff]

You think this is new? If a program, or rather a computer, is restricted to
a finite number of states (which all modern computers are) then it's nothing
more than a finite automaton and therefore the halting problem for these
machines is solvable *in theory*. Practically, given the size of available
memory on todays machines, for most problems I'd say it's not. Also, the metod
you described is nothing new, it's a commonly used metod to find cycles in
iterative procedures (hey, A. K. Dewdney has described it in his column in
Scientific American, so everyone - give or take a few - should be familiar
with it :-).  Solving the halting problem for a Turing machine (or any other
machine with unlimited memory) is something entirely different.


| Christer Ericson            Internet: christer@cs.umu.se [130.239.1.101] |
| Department of Computer Science, University of Umea, S-90187 UMEA, Sweden |

gudeman@cs.arizona.edu (David Gudeman) (11/14/90)

In article  <3975:Nov1323:25:4390@kramden.acf.nyu.edu> Dan Bernstein writes:
]Here are two articles about the practical solution to the halting
]problem...

This isn't a solution to the halting problem, it's a solution to the
problem of determining whether a program ever enters the same state
twice --which is neither a sufficient nor necessary condition for a
program to be non-terminating.  That, unless you include the entire
universe of things that might effect the program in the state (input
futures and such).  In that case it is a sufficient but still not
necessary condition for non-termination.

You could probably get a better approximate solution by a static
analysis of the program, and it would not effect run-time parameters.
-- 
					David Gudeman
Department of Computer Science
The University of Arizona        gudeman@cs.arizona.edu
Tucson, AZ 85721                 noao!arizona!gudeman

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/15/90)

In article <27477@megaron.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes:
> In article  <3975:Nov1323:25:4390@kramden.acf.nyu.edu> Dan Bernstein writes:
> ]Here are two articles about the practical solution to the halting
> ]problem...
> This isn't a solution to the halting problem, it's a solution to the
> problem of determining whether a program ever enters the same state
> twice--which is neither a sufficient nor necessary condition for a
> program to be non-terminating.

More abstract silliness. Perhaps you forgot that the computational model
is finite. The halting problem *is* the cycle problem.

In practice, non-terminating programs enter a rather simple infinite
loop. But this is irrelevant to the theoretical correctness of the
method.

I advise that you read the articles, which allude to these non-problems.

> You could probably get a better approximate solution by a static
> analysis of the program,

No, you cannot, just as you cannot optimize arrays into pointers by a
static analysis.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/15/90)

In article <1990Nov14.150535.25991@cs.umu.se> christer@cs.umu.se (Christer Ericson) writes:
> In article <3975:Nov1323:25:4390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
    [ on the practical solution to the halting problem ]
> You think this is new?

No, I don't. I think computer science (as opposed to real-world computer
programming) has regressed more than it has progressed in the last
twenty years.

In particular, modern computer scientists believe that the best known
sorting methods are asymptotically suboptimal. They believe the dogma
about the halting problem so firmly that they refuse to think through to
a practical solution. So when I remind people of what was widely known
in the sixties, I get attacked for my ``mathematical mistakes.''

> If a program, or rather a computer, is restricted to
> a finite number of states (which all modern computers are) then it's nothing
> more than a finite automaton and therefore the halting problem for these
> machines is solvable *in theory*.

Right. It's also solvable in practice.

> Practically, given the size of available
> memory on todays machines, for most problems I'd say it's not.

Are you trying to contribute to this discussion? In the article you're
responding to I gave quite precise estimates of the amount of work
necessary: twice as much memory for the variables you want to detect
cycling, and three times slower not counting housekeeping whenever those
variables are used. Now you express some vague opinion that this is not
practical, when obviously factors of two and three are the norm during
debugging.

> Also, the metod
> you described is nothing new, it's a commonly used metod to find cycles in
> iterative procedures

In fact, I didn't even bother to review the details of how to detect
loops in general, because any reader who doesn't understand can look up
the exercises in Knuth.

> Solving the halting problem for a Turing machine

We are talking about practical problems, not Turing machines.

---Dan

gessel@carthage.cs.swarthmore.edu (Daniel Mark Gessel) (11/15/90)

In article <13350:Nov1419:44:2790@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
   In article <27477@megaron.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes:
   > In article  <3975:Nov1323:25:4390@kramden.acf.nyu.edu> Dan Bernstein writes:
   > ]Here are two articles about the practical solution to the halting
   > ]problem...
   > This isn't a solution to the halting problem, it's a solution to the
   > problem of determining whether a program ever enters the same state
   > twice--which is neither a sufficient nor necessary condition for a
   > program to be non-terminating.

   More abstract silliness. Perhaps you forgot that the computational model
   is finite. The halting problem *is* the cycle problem.

   In practice, non-terminating programs enter a rather simple infinite
   loop. But this is irrelevant to the theoretical correctness of the
   method.

   I advise that you read the articles, which allude to these non-problems.

   > You could probably get a better approximate solution by a static
   > analysis of the program,

   No, you cannot, just as you cannot optimize arrays into pointers by a
   static analysis.

   ---Dan

The Halting Problem is _not_ the cycle problem. The Computational Model is
a Turing Machine, not a computer with finite memory. 

The problem of determining whether or not a program goes into an infinite
loop is The Halting Problem, given that the language it is written in can
do dynamic allocation under the assumption that dynamic allocation will not
fail. If you assume that dynamic allocation will fail at some point, you
may be able to do some worthwhile analysis, and may be able to determine if a
program halts. I don't actually know. 

The Halting Problem is by definition abstract silliness.

Whether or not a computer program will stop depends exactly on your definition
of a computer program. The mathematical definition of an algorithm is 
equivalent to a turing machine, as far as anyone knows, and if you can
prove differently, you will become quite famous. For this definition of
an algorithm, the halting problem is unsolvable by a turing machine.

Dan

--
Daniel Mark Gessel                          Independent Software Consultant
Internet: gessel@cs.swarthmore.edu                  
I do not represent the opinions of Swarthmore College.

gudeman@cs.arizona.edu (David Gudeman) (11/15/90)

In article  <13350:Nov1419:44:2790@kramden.acf.nyu.edu> Dan Bernstein writes:
]In article <27477@megaron.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes:
]> This isn't a solution to the halting problem, it's a solution to the
]> problem of determining whether a program ever enters the same state
]> twice...
]
]More abstract silliness. Perhaps you forgot that the computational model
]is finite. The halting problem *is* the cycle problem.
]
]In practice, non-terminating programs enter a rather simple infinite
]loop.

I was objecting on practical grounds, not theoretical ones.  Since, as
you point out, a real computer is finite, the halting problem is
theoreticaly solvable for them, but it is not clear that you have
presented a _practical_ solution.  It is not the case that all forms
of non-termination involve "rather simple infinite loops", nor is it
clear that this is the case in practice either.  (Such forms of
non-termination, by the way, are usually easy to find by static
analysis.)

In _practice_, a computer program has a huge number of states, and
there is no reason to suppose that an infinite loop will cover only a
small set of states.  Even if the loop is doing something as simple as
incrementing a few variables, say n, then the number of states in a
cycle is on the order of MaxInteger^n.  How long, on average, do you
think it will take to detect loops in such a set of states?

Your method can take arbitrarily long to detect an infinite loop, and
in _practice_ if it takes too long it may as well never terminate.  So
the _practical_ effect of your method is that it will sometimes
terminate with an answer ("infinite loop" or "no infinite loop") and
will sometimes never terminate.  Any theoretician can tell you that
such a test is possible, so I don't see any justification behind your
negative comments about computer science.  It seems to me that
practice follows theory quite closely here.

This is not to suggest that it is worthless to do anything about
infinite loops.  There are approximate solutions known, but most
people are careful to observe that the solutions are approximate, and
only detect some subset of non-terminating programs.  Saying that you
have a "practical solution to the halting problem" is deliberately
antagonistic, as well as incorrect.  Your solution is either a
practical partial way to detect _some_ non-terminating programs, in
which case it is not a "solution" in the technical sense of the word,
or it is a true solution to the problem of using finite state machines
to detect non-termination on other finite state machines.  But in this
case it is not "practical", since there are many problems for which it
will not terminate in a reasonable time.

]> You could probably get a better approximate solution by a static
]> analysis of the program,
]
]No, you cannot, just as you cannot optimize arrays into pointers by a
]static analysis.

Are you suggesting that there is some connection here?

And would you care to give some references to support this statement?
(Not the connection, the assertion that you cannot get a better
approximation by static analysis.)  I'm curious as to how you are
defining "better" in such a way that you can state this as a fact
rather than as an opinion.
-- 
					David Gudeman
Department of Computer Science
The University of Arizona        gudeman@cs.arizona.edu
Tucson, AZ 85721                 noao!arizona!gudeman

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (11/15/90)

In article <3975:Nov1323:25:4390@kramden.acf.nyu.edu>,
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> Here are two articles about the practical solution to the halting
> problem.

The technique referred to is commonly known as "Tortoise and Hare".
It's a very handy technique for programs that wander around graphs
and other finite data structures.

Most of the non-terminating loops my programs go into involve constructing
ever larger data structures, so tend to be detected by the storage allocator...

Eiffel is one of the few languages around which provides for termination tests:
when you write a loop you can provide an expression whose value must decrease
on each iteration, while remaining non-negative.  If it goes negative or fails
to decrease, the informal proof of termination you presumably had in mind when
you wrote the loop is flawed.  An old idea and a simple one.  It's _very_ nice
to see it actually provided as a debugging tool that's easy to use.
-- 
The problem about real life is that moving one's knight to QB3
may always be replied to with a lob across the net.  --Alasdair Macintyre.

oz@yunexus.yorku.ca (Ozan Yigit) (11/15/90)

In article <3975:Nov1323:25:4390@kramden.acf.nyu.edu>
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes on the halting
problem:

>		The practical solution is that we run the program
>on two machines with that number of states, one machine exactly twice as
>fast as the other; if the program loops in time t to t+u, then we will
>see the machines in exactly the same state at time 3t to 3t+3u.

This sounds exactly like an old lisp algorithm for determining whether or
ot a list is in fact circular. For example, the scheme code that determines
list-length while checking circularity looks like this:
	
	(define (list-length lst) (elen lst lst 0))
	(define (elen slow fast n)
	  (cond 
	   [(null? fast) 	n]
	   [(null? (cdr fast))  (1+ n)]
	   [(and (eq? fast slow) (not (= n 0))) "cycle in list"]
	   (else
	    (elen (cdr slow) (cddr fast) (+ n 2)))))
	
	;;; (set! foo '(a b c d e f g h i j))
	;;; (list-length foo)
	;;; (set-cdr! (list-tail foo 9) foo)
	;;; (list-length foo)


So, what is the big fuss about?

oz
---
Where the stream runneth smoothest,   | Internet: oz@nexus.yorku.ca 
the water is deepest.  - John Lyly    | UUCP: utzoo/utai!yunexus!oz

  

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/16/90)

If you have a program with a set of variables that enter a loop at time
t, and continue to loop in a cycle of length l, then the method outlined
will run the program in twice the memory at one-third speed minus
housekeeping, and detect the loop between t and t + l, i.e., during its
first cycle.

That's all the practical solution to the halting problem does; interpret
it as you wish. It's practical because the slowdown and memory waste are
practical during debugging, and because t and l are relatively small in
most practical cases. It's a solution to the halting problem because in
the worst case it'll still detect the loop eventually, though I don't
think these theoretical statements matter for the real world.

In article <GESSEL.90Nov14165831@carthage.cs.swarthmore.edu> gessel@carthage.cs.swarthmore.edu (Daniel Mark Gessel) writes:
>    > ]Here are two articles about the practical solution to the halting
>    > ]problem...
> The Halting Problem is _not_ the cycle problem. The Computational Model is
> a Turing Machine, not a computer with finite memory. 

See, this is what I mean about computer scientists. The computational
model I work with is realistic---it's just my mental picture of what can
be coded on lots of real machines. As I said before, it's finite. It has
very, very little to do with a Turing machine.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/16/90)

In article <27498@megaron.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes:
> In article  <13350:Nov1419:44:2790@kramden.acf.nyu.edu> Dan Bernstein writes:
> ]In practice, non-terminating programs enter a rather simple infinite
> ]loop.
  [ disagreement ]

Well, I can't remember ever debugging a non-terminating program that
*didn't* have a rather simple infinite loop, and I remember debugging
lots of programs where the loop was simple. Does your experience differ?
I'd be interested in seeing your example.

> Any theoretician can tell you that
> such a test is possible, so I don't see any justification behind your
> negative comments about computer science.

Not long ago in this thread I remarked that the halting problem is
solvable in practice. The response I got---from a computer scientist---
was religious disbelief. It doesn't take much thought to apply theory to
practice and put some reasonable bounds on the resources necessary to
discover a loop---but computer scientists *don't do it*.

> or it is a true solution to the problem of using finite state machines
> to detect non-termination on other finite state machines.

Yes, that is correct.

> But in this
> case it is not "practical", since there are many problems for which it
> will not terminate in a reasonable time.

Here we disagree about what problems come up in practice, and I'd be
interested in seeing your examples of those problems.

> ]> You could probably get a better approximate solution by a static
> ]> analysis of the program,
> ]No, you cannot, just as you cannot optimize arrays into pointers by a
> ]static analysis.
> Are you suggesting that there is some connection here?

Just undecidability. Of course, if you were to believe some of the
people who argued with me in this group, you'd believe that sorting is
not linear in the number of bytes being sorted, that finding the optimal
pointer version of array code is decidable (NP, in fact---check out
Jim's articles over the past week), and also that the moon is made of
green cheese. Well, maybe not that last one.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/16/90)

In article <4279@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
> In article <3975:Nov1323:25:4390@kramden.acf.nyu.edu>,
> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> > Here are two articles about the practical solution to the halting
> > problem.
> The technique referred to is commonly known as "Tortoise and Hare".
> It's a very handy technique for programs that wander around graphs
> and other finite data structures.

Maybe computer science actually hasn't been regressing in Australia.
Thanks for confirming that someone else in the world knows what everyone
knew when the words ``computer science'' sounded funny...

People who aren't familiar with loop detection should look in Knuth,
exercises 3.1-6 and -7 (I think; I don't have the book handy).

  [ Eiffel termination tests ]
> when you write a loop you can provide an expression whose value must decrease
> on each iteration, while remaining non-negative.

You can apply Q's invariants in similar ways.

People who aren't familiar with these techniques should look in Knuth,
chapter 1, the first section on Euclid's algorithm.

---Dan

misha@just-right.ai.mit.edu (Mike Bolotski) (11/16/90)

In article <5785:Nov1519:19:5390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>If you have a program with a set of variables that enter a loop at time
>t, and continue to loop in a cycle of length l, then the method outlined
>will run the program in twice the memory at one-third speed minus
>housekeeping, and detect the loop between t and t + l, i.e., during its
>first cycle.

That's fine, Dan. What if the cycle length is several millenia?

It's not hard to write a simple program that uses say, 256-bit
integers which accomplishes that.  Your "solution" is hardly practical.

And here's a quick test for your solution:

int foo(x)
int256 x;
{
  while (x != 1) 
    if (even(x))  x = x / 2;
        else x = x * 3 + 1;       
  return 1;
}

>the worst case it'll still detect the loop eventually, though I don't
>think these theoretical statements matter for the real world.

The real world being defined as your experience alone, is it?

>See, this is what I mean about computer scientists. The computational
>model I work with is realistic---it's just my mental picture of what can
>be coded on lots of real machines. As I said before, it's finite. It has

No need to apologize for your limitations, Dan.







Mike Bolotski          Artificial Intelligence Laboratory, MIT
misha@ai.mit.edu       Cambridge, MA

misha@just-right.ai.mit.edu (Mike Bolotski) (11/16/90)

In article <6045:Nov1519:34:2290@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>Just undecidability. Of course, if you were to believe some of the
>people who argued with me in this group, you'd believe that sorting is
>not linear in the number of bytes being sorted, that finding the optimal
>pointer version of array code is decidable (NP, in fact---check out
>Jim's articles over the past week), and also that the moon is made of
>green cheese. Well, maybe not that last one.

Just keep putting your foot in your mouth, Dan.   And I like the
ever-so-subtle transition from optimal addition sequence to 
pointer version of array code.  

And just how seriously do you expect your opinions to be taken if
you haven't read the basic references about compiler construction
or theory of computation?


Mike Bolotski          Artificial Intelligence Laboratory, MIT
misha@ai.mit.edu       Cambridge, MA

new@ee.udel.edu (Darren New) (11/16/90)

In article <5785:Nov1519:19:5390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>See, this is what I mean about computer scientists. The computational
>model I work with is realistic---it's just my mental picture of what can
>be coded on lots of real machines. As I said before, it's finite. It has
>very, very little to do with a Turing machine.

But the program you write to do the testing you describe requires some memory.
Hence, because of your finite machine, there are some problems which the 
program under test cannot solve which it would have been able to solve had
you given it that extra memory. If it cannot solve the problem (i.e., if it
gives a different answer) then it might go into a loop.  For example, let's
try this pseudoprogram:

const x = any integer;
begin
  for i := 0 to x do begin
    y = malloc(1);
    if (y == NULL) begin
	while (1) ;
	end
    end
end.

For any given size machine, there will be a value for X where the program
will not halt when you test it but will halt if you run it alone.  An "almost
right" solution to the halting problem may be useful, but I wouldn't call it
"a practical solution to the halting problem".      -- Darren
    
-- 
--- Darren New --- Grad Student --- CIS --- Univ. of Delaware ---
----- Network Protocols, Graphics, Programming Languages, 
      Formal Description Techniques (esp. Estelle), Coffee, Amigas -----
              =+=+=+ Let GROPE be an N-tuple where ... +=+=+=

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/16/90)

In article <11897@life.ai.mit.edu> misha@just-right.ai.mit.edu (Mike Bolotski) writes:
> In article <5785:Nov1519:19:5390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> >If you have a program with a set of variables that enter a loop at time
> >t, and continue to loop in a cycle of length l, then the method outlined
> >will run the program in twice the memory at one-third speed minus
> >housekeeping, and detect the loop between t and t + l, i.e., during its
> >first cycle.
> That's fine, Dan. What if the cycle length is several millenia?

Then it will be detected in at most several times three millenia. But
I've never seen this happen *in practice*.

Have you ever debugged a program to find an infinite loop that would
take such a long time, or are you just arguing for the sake of argument?
A few examples of the former wouldn't diminish the practical value of
the solution, but I'd be interested in seeing them anyway.

> >the worst case it'll still detect the loop eventually, though I don't
> >think these theoretical statements matter for the real world.
> The real world being defined as your experience alone, is it?

Again, I invite comments from anyone whose experience differs. I haven't
seen any such comments yet.

> >See, this is what I mean about computer scientists. The computational
> >model I work with is realistic---it's just my mental picture of what can
> >be coded on lots of real machines. As I said before, it's finite. It has
> No need to apologize for your limitations, Dan.

I insist upon apologizing. I simply cannot bring myself to imagine a
computer with an infinite amount of memory. When I imagine a byte being
sent to memory, the computer explodes and settles into dust. When I
picture a Turing machine, it has a lot of tape stretching off into the
distance, but I just can't see each and every bit on the tape all at
once. Maybe this is just because in my finite experience I've never seen
how an infinite computer would work, or where it would be stored.

I'm also a firm believer in propositional set theory, if you're
mathematically inclined enough to know what that is. Tarski's last book
(with Givant) is my bible on these matters.

If you in your infinite wisdom would deign to explain to me how to
visualize the infinitely powerful computer of yours, I'd be eternally
grateful. No, scrap that, I'd be finitely grateful.

---Dan

gudeman@cs.arizona.edu (David Gudeman) (11/16/90)

In article  <6045:Nov1519:34:2290@kramden.acf.nyu.edu> Dan Bernstein writes:
]Well, I can't remember ever debugging a non-terminating program that
]*didn't* have a rather simple infinite loop, and I remember debugging
]lots of programs where the loop was simple. Does your experience differ?

The word "simple" here is ambiguous.  If you mean that the loop was
fairly small, I guess most of them are.  If you mean that the number
of states traversed in a cycle is small, then yes, my experience
differs.  It seems to me that there is almost always at least some
monotonic action going on in a loop (which is the reason for having
the loop), and this action will create very long state cycles.

]I'd be interested in seeing your example.

Here's the simplest form: you accidentally use the wrong exit
condition:

  for (i = start; i != -1; i++) ...

If "start" begins as a non-negative number, you've got a long wait
ahead of you.

]Not long ago in this thread I remarked that the halting problem is
]solvable in practice. The response I got---from a computer scientist---
]was religious disbelief.

Oh, well.  If I'd known you had such a huge sample space, I would
never have had the nerve to question you.  I guess if I have
enountered one beligerant mathematician I can just assume this is
typical of the field.

And furthermore, you have _not_ solved it.  If your proposal were
implemented there would still be programs that would never --for all
practical purposes-- terminate.  How has life changed?  All you have
done is decreased the likelihood of such an eventuallity, by some
unknown amount that --in the absence of further evidence-- reasonable
people can disagree on.

] It doesn't take much thought to apply theory to
]practice and put some reasonable bounds on the resources necessary to
]discover a loop---but computer scientists *don't do it*.

There are a lot of things that should be done that no one has time
for.  There is so much _real_ research involved in designing and
implementing programming languages, that this just hasn't recieved
much attention.  It is far from being the most important thing that
has been neglected in the field.  Many of us would even go so far as
to say that this is not a matter of research, but of engineering, and
therefore outside the realm of computer science.

]Just undecidability.

Hmm.  Are you claiming here that if something is undecideable in
theory that there is necessarily no practical approximation?  Weren't
you just bashing an anonymous computer scientist for such an opinion?

] Of course, if you were to believe some of the
]people who argued with me in this group, you'd believe that sorting is
]not linear in the number of bytes being sorted

Depends on your model.  Assertions about the complexity of sorting
rely by necessity on the underlying model.  I can produce a model
where sorting time is a constant.  As to whether your model is better
than others, that is a matter of opinion.  Personally, I happen to
agree with you on this one, but I wouldn't go about insulting people
because they disagree with me.

] that finding the optimal
]pointer version of array code is decidable

Again, a matter of the model in use.  Everyone else in the world was
assuming a model where the weights of the paths was given as part of
the input (or assumed to be uniform).  After you finally clued us in
about how your model differed, the argument degenerated to opinions on
models.
-- 
					David Gudeman
Department of Computer Science
The University of Arizona        gudeman@cs.arizona.edu
Tucson, AZ 85721                 noao!arizona!gudeman

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/16/90)

In article <36480@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes:
> In article <5785:Nov1519:19:5390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> >See, this is what I mean about computer scientists. The computational
> >model I work with is realistic---it's just my mental picture of what can
> >be coded on lots of real machines. As I said before, it's finite. It has
> >very, very little to do with a Turing machine.
> But the program you write to do the testing you describe requires some memory.

Did you read the original description? The first setup I described has
two computers, side by side, one running twice as fast as the other.
Cache chips---which already do almost all the necessary work---handle
the housekeeping. There is no memory loss. The programs work as usual.

If your machine is multiprocessing, then it's better to have two
processes running side by side than to duplicate the hardware. This does
imply some memory use---but in such an environment you can't assume a
fixed memory size anyway.

> For any given size machine, there will be a value for X where the program
> will not halt when you test it but will halt if you run it alone.  An "almost
> right" solution to the halting problem may be useful,

Your objections are based upon the supposed change in the computer's
configuration. Hence they are moot.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/16/90)

In article <11900@life.ai.mit.edu> misha@just-right.ai.mit.edu (Mike Bolotski) writes:
> And I like the
> ever-so-subtle transition from optimal addition sequence to 
> pointer version of array code.  

See, this is what I mean about computer scientists. Anyone who bothers
to think about the problem will understand why, in a general
computation, converting array references to pointer references is the
same as finding an optimal addition chain. (Hint: In machine language,
how are array references implemented?)

By the way, why do you insist upon repeatedly misquoting the phrase
``optimal addition chain in a general computation''? Which word don't
you understand?

> And just how seriously do you expect your opinions to be taken if
> you haven't read the basic references about compiler construction
> or theory of computation?

I have read each of the AHU/ASU/etc books. Once. I find none of them
particularly useful as references, as everything they say is presented
more to my taste either in Knuth or in original research articles. I
certainly find it amusing that you consider the currently fashionable
elementary textbooks to be ``basic references.''

---Dan

new@ee.udel.edu (Darren New) (11/16/90)

In article <27546@megaron.cs.arizona.edu> gudeman@cs.arizona.edu (David Gudeman) writes:
>In article  <6045:Nov1519:34:2290@kramden.acf.nyu.edu> Dan Bernstein writes:
>]Well, I can't remember ever debugging a non-terminating program that
>]*didn't* have a rather simple infinite loop, and I remember debugging
>]lots of programs where the loop was simple. Does your experience differ?
>
>The word "simple" here is ambiguous.  If you mean that the loop was
>fairly small, I guess most of them are.  If you mean that the number
>of states traversed in a cycle is small, then yes, my experience
>differs.  It seems to me that there is almost always at least some
>monotonic action going on in a loop (which is the reason for having
>the loop), and this action will create very long state cycles.
>
>]I'd be interested in seeing your example.
>

Here is a really simple example that has stung me a couple of times. Once,
this ran for two days before I noticed it had never finished.

$ cat xyz* >xyzzy

This will eventually fill up the entire disk, never once entering the same
state.                  -- Darren
-- 
--- Darren New --- Grad Student --- CIS --- Univ. of Delaware ---
----- Network Protocols, Graphics, Programming Languages, 
      Formal Description Techniques (esp. Estelle), Coffee, Amigas -----
              =+=+=+ Let GROPE be an N-tuple where ... +=+=+=

misha@gracilis.ai.mit.edu (Mike Bolotski) (11/17/90)

In article <13046:Nov1604:16:4390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>See, this is what I mean about computer scientists. 

Actually, Dan, I happen to be an electrical engineer.

> Anyone who bothers
>to think about the problem will understand why, in a general
>computation, converting array references to pointer references is the
>same as finding an optimal addition chain. (Hint: In machine language,
>how are array references implemented?)

Hint: a general computation does not require arrays at all.

>>By the way, why do you insist upon repeatedly misquoting the phrase
>``optimal addition chain in a general computation''? Which word don't
>you understand?

Oh, I understand all of the above words as used in the conventional
literature.  Seeing as you insist on redefining each of them to suit
your current argument of the day, I suppose it would be helpful if
you went ahead and actually defined your terminology.

>> And just how seriously do you expect your opinions to be taken if
>> you haven't read the basic references about compiler construction
>> or theory of computation?
>
>I have read each of the AHU/ASU/etc books. Once. I find none of them
>particularly useful as references, as everything they say is presented
>more to my taste either in Knuth or in original research articles. I
>certainly find it amusing that you consider the currently fashionable
>elementary textbooks to be ``basic references.''

Basic, Dan. As in: "you have to be familiar with the content to be taken
seriously."  Now, either you've read the books and disagree with the
authors,  or you haven't read the books closely enough to comment.

Now, about that quote I provided. Do you agree with the authors
or do your basic definitions differ?

And I'm getting close to Jim's level of frustration with discussing
anything with you. How about steering the discussion away from
ad hominem attacks, accusations of lying, etc, etc, and back to
technical issues.  For starters, you could answer my question about
the ASU quote.





Mike Bolotski          Artificial Intelligence Laboratory, MIT
misha@ai.mit.edu       Cambridge, MA

dbc@bushido.uucp (Dave Caswell) (11/18/90)

.There does not exist an algorithm that will convert an (optimal) array
.program into its optimal pointer form. That summarizes what I've said so
.far in this thread.
.
.What does it mean for real languages? It means that the programmer
.*must* be allowed to look at an array x from the vantage point of x[a],
.rather than x[0]. This array shifting doesn't have to look like C's

Clearly that isn't a proof.  The word "*must*" is inappropriate in that
context.

-- 
David Caswell                             dbc%bushido.uucp@umich.edu

smryan@garth.UUCP (Steven Ryan) (11/20/90)

>> If a program, or rather a computer, is restricted to
>> a finite number of states (which all modern computers are) then it's nothing
>> more than a finite automaton and therefore the halting problem for these
>> machines is solvable *in theory*.
>
>Right. It's also solvable in practice.

I assume this includes checking each reel of tape in the library that the
program has accessed, each reel of tape that the program accessed but have
been moved off site because the tape library is full, and eventually every
reel of tape which was moved off planet because the planet is full.

Can you really put an a priori bound on the length of the tape? I suppose
we could put bounds based on the number of atoms in the universe, IF you
can deduce the number of atoms. (Deduce is not the same thing physics does.)
-- 
...!uunet!ingr!apd!smryan                                       Steven Ryan
...!{apple|pyramid}!garth!smryan              2400 Geng Road, Palo Alto, CA

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/20/90)

In article <1990Nov18.024745.2424@bushido.uucp> dbc@bushido.uucp (Dave Caswell) writes:
> .There does not exist an algorithm that will convert an (optimal) array
> .program into its optimal pointer form. That summarizes what I've said so
> .far in this thread.
> .What does it mean for real languages? It means that the programmer
> .*must* be allowed to look at an array x from the vantage point of x[a],
> .rather than x[0]. This array shifting doesn't have to look like C's
> Clearly that isn't a proof.  The word "*must*" is inappropriate in that
> context.

You're right. What I should have said was ``If the language doesn't let
the programmer look at [etc.] ... then it will be restricting his
freedom to express certain optimizations.''

To a language designer, that means that the language *must* provide some
equivalent feature; but most people don't care to design languages.

---Dan

jrbd@craycos.com (James Davies) (11/21/90)

>> If a program, or rather a computer, is restricted to
>> a finite number of states (which all modern computers are) then it's nothing
>> more than a finite automaton and therefore the halting problem for these
>> machines is solvable *in theory*.
>
>Right. It's also solvable in practice.

main(argc,argv) {

	int I_halt();

	if (I_halt(argv[0])) {
		while(1);
	} else {
		exit(0);
	}
}

Please write I_halt.  It should return 1 if its argument program
halts, 0 if it doesn't.  Feel free to consult books or notes,
other programmers, Nobel prize winners, etc.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/21/90)

Skip if you saw James' error.

In article <1990Nov20.213454.10879@craycos.com> jrbd@craycos.com (James Davies) writes:
> >>If a program, or rather a computer, is restricted to
> >>a finite number of states (which all modern computers are) then it's nothing
> >>more than a finite automaton and therefore the halting problem for these
> >>machines is solvable *in theory*.
> >Right. It's also solvable in practice.
> main(argc,argv) {
> 	int I_halt();
> 	if (I_halt(argv[0])) {
> 		while(1);
> 	} else {
> 		exit(0);
> 	}
> }
> Please write I_halt.  It should return 1 if its argument program
> halts, 0 if it doesn't. 

We are all aware that it is impossible for a fixed algorithm *within*
machine M to solve the halting problem for machine M (provided that M is
not utterly trivial). But the solution takes advantage of a new machine
*outside* M. Your artificially restricted question has nothing to do
with the problem at hand.

> Feel free to consult books or notes,
> other programmers, Nobel prize winners, etc.

Your sarcasm would be more appropriate if you had shown that you
understood anything written in previous articles in this thread.

---Dan

smryan@garth.UUCP (Steven Ryan) (11/22/90)

You may find this shocking, but some of us don't care if array references
can be made optimal--for the machine. How about array references which are
optimal for the programmer? Neither C nor Fortran do that as well as Algol
60 did, thirty years ago.

There are other considerations than grinding out the fastest possible object
code.
-- 
...!uunet!ingr!apd!smryan                                       Steven Ryan
...!{apple|pyramid}!garth!smryan              2400 Geng Road, Palo Alto, CA