Why does this tiny program NOT work??!? 
Author Message
 Why does this tiny program NOT work??!?

I found in an old book on Forth (about 1984) a small sieve that serves me very
well as a crude benchmark. The strange thing is that newer compilers don't seem
to execute this little piece of code (Cforth does, FPC does, so does LMI forth
and so does 4tH; This4th doesn't and PFC does neither):

variable line

: test mod 0= ;

: print
  dup 5 .r

  if cr drop 4
     else 1 -
  then
  line !
;

: ptest
  dup 2 / 2
  do
    dup i test
    if 0 leave
    then
  loop
  dup
  if print
     else drop
  then drop
;

: prime
  cr
  4 line !
  do i ptest loop
  cr
;

I did some tests with PTEST and got some strange results. 7 works, 5 doesn't

Forth-83. Which definition has changed since then in such a way that this thing
doesn't work anymore?

Anybody any ideas?



Sun, 02 Nov 1997 03:00:00 GMT  
 Why does this tiny program NOT work??!?

Quote:
>: ptest
>  dup 2 / 2
>  do
>    dup i test
>    if 0 leave
>    then
>  loop
>  dup
>  if print
>     else drop
>  then drop
>;
>I did some tests with PTEST and got some strange results. 7 works, 5 doesn't

>Forth-83. Which definition has changed since then in such a way that this thing
>doesn't work anymore?

It's DO which has generated a lot of complaints since 1983.

2 2 DO would go around a long time.  But when it reaches 5 it thinks it has a factor
and it quits.

0 2 DO goes around almost as long, and it never reaches 1 to think it's done.  I'm
not clear whether at the very end it will do 0 MOD and get a division by zero or not,
it would take it a while to get that far regardless.



Sun, 02 Nov 1997 03:00:00 GMT  
 Why does this tiny program NOT work??!?

Quote:
> I found in an old book on Forth (about 1984) a small sieve that serves me very
> well as a crude benchmark.

Note, that the definitions you gave do not implement the sieve
algorthim to find prime numbers but does a simple repetitive
divisable test to check if a given number is a prime number.

Throwing in some stack comments, we might find some inconsistencies or
problems:

variable line

: test ( p n -- f ) mod 0= ;  \ What a nice nothing telling name.

: print ( p -- p )
\ Note, that print does not consume its argument. Poor style?
   dup 5 .r         ( p )

   if cr drop 4
      else 1 -
   then
   line !
;

: ptest ( p -- )
\ Due to the unecessary unbalanced LOOP-exits, I consider this definition
\ extremely poor Forth code.
   dup 2 / 2           ( p p/2 2 )
   do                  ( p )
     dup i test        ( p f )
     if 0 leave        ( p 0 )
     then              ( p )
   loop                ( p | p 0 )
   dup                 ( p p | p 0 0 )
   if                  ( p )
      print            ( p )
      else             ( p 0 )
           drop        ( p )
   then                ( p )
   drop                ( )
;

: prime ( to from -- )
   cr
   4 line !
   do i ptest loop ( )
   cr
;

Quote:
> I did some tests with PTEST and got some strange results. 7 works, 5

> Forth-79 and Forth-83.  Which definition has changed since then in
> such a way that this thing doesn't work anymore?

I think the problem in this example is the DO loop. Given 5 as argument,
PTEST will execute a 2 2 DO LOOP  which will run the full number circle
if not left meanwhile. Fortunately 5 5 TEST will return true and so
this loop is left nearly immediately.  The loop in 1 PTEST  (0 2 DO LOOP)
will not be left since  1 I TEST will always return false.

Quote:
> Anybody any ideas?

I came up with the following ANS Forth standard program:

: divided? ( n1 n2 -- f )  MOD 0= ;
\ Return true iff n2 divides n1 (n1 is divided by n2).  
\ Same result with floored and symmetrical division since arguments are positive.

: prime? ( n -- f )
  DUP 1 =        IF  DROP FALSE EXIT THEN  ( n )
  DUP 2 divided? IF  DROP FALSE EXIT THEN  ( n )
  3   ( n n1 )
  BEGIN ( n n1 )
    2DUP DUP * <  IF  2DROP  TRUE EXIT THEN ( n n1 )
    2DUP divided? IF  2DROP FALSE EXIT THEN ( n n1 )
    2+
  AGAIN ;    

\ Note that this algorithm is different from (and more efficient than) the one
\ above.
\ 1) Apart from 2 it tests only odd denominators and
\ 2) it tests only upto (and including) the square-root of the potential
\    prime number, which is sufficient.
\
\ I believe PRIME? is much a better factor than PTEST above, since it does no
\ IO. PRIME? can be reused in definitions like:
\
\ : next-prime ( n -- n' ) BEGIN 1+ DUP prime? UNTIL ;
\ or
\ : prime-twin? ( n -- )  DUP prime?  OVER 2+ prime? and ;

: prime ( to from -- )  ?DO I prime? IF  I . THEN LOOP ;

Ulrich

--
Ulrich Hoffmann, Uni Kiel        WWW: http://www.informatik.uni-kiel.de/~uho/

Preusserstr 1-9, D-24105 Kiel, Germany      Tel: +49 431 560426   Fax: 566143



Tue, 04 Nov 1997 03:00:00 GMT  
 Why does this tiny program NOT work??!?

| I found in an old book on Forth (about 1984) a small sieve that serves me ver
| well as a crude benchmark. The strange thing is that newer compilers don't se
| to execute this little piece of code (Cforth does, FPC does, so does LMI fort
| and so does 4tH; This4th doesn't and PFC does neither):
|
| variable line
|
| : test mod 0= ;
|
| : print
|   dup 5 .r

|   if cr drop 4
|      else 1 -
|   then
|   line !
| ;
|
| : ptest
|   dup 2 / 2
|   do
|     dup i test
|     if 0 leave
|     then
|   loop
|   dup
|   if print
|      else drop
|   then drop
| ;
|
| : prime
|   cr
|   4 line !
|   do i ptest loop
|   cr
| ;
|
| I did some tests with PTEST and got some strange results. 7 works, 5 doesn't

| Forth-83. Which definition has changed since then in such a way that this thi
| doesn't work anymore?
|
| Anybody any ideas?
|
|
|
|

i don't know why it should be 0 LEAVE up there.  perhaps i'm not fluent
enough, but LEAVE always works well enough for me.

--- email: uwvax!gorgon!ruth!spqr
"Hit paydirt with KDRT!" -- Ford Fairlane, Rock & Roll detective.



Fri, 07 Nov 1997 03:00:00 GMT  
 Why does this tiny program NOT work??!?

| variable line
|
| : test mod 0= ;

| : print
|   dup 5 .r

|   if cr drop 4
|      else 1 -
|   then
|   line !
| ;

| : ptest
|   dup 2 / 2
|   do
|     dup i test
|     if 0 leave
|     then
|   loop
|   dup
|   if print
|      else drop
|   then drop
| ;

| : prime
|   cr
|   4 line !
|   do i ptest loop
|   cr
| ;

Quote:
>i don't know why it should be 0 LEAVE up there.  perhaps i'm not fluent
>enough, but LEAVE always works well enough for me.

He wanted to leave a flag to show whether or not to print the word; if it
LEAVEs then it isn't prime and he doesn't print it.  Then the routine "print"
leaves a copy behind to be dropped later, but the zero gets dropped instead
of printed.

I'd probably revise that this way, if I wasn't thinking much:

 : print ( +n -- )
   5 .r

   if cr drop 4
      else 1-
   then
   line !
 ;

 : prime? ( +n -- +n|0 )
   dup 2/ 2
   do
     dup i test
     if 0= unloop exit
     then
   loop
;
: ptest ( +n -- )
   dup prime?
   if print then
 ;

With more thought I'd start changing the algorithm, maybe first divide by 2
and odd numbers, and stop at the square root, and maybe some sort of way to
only divide by primes.  But the original purpose was to do some sort of crude
speed benchmarking.  Any changes make the result hard to compare with
benchmarks run with the old code.  So cleaning it up is useless.



Sun, 09 Nov 1997 03:00:00 GMT  
 Why does this tiny program NOT work??!?
   I believe you'll find that the definition of LOOP and LEAVE have
changed in the Forth-83 compilers. Forth-79 used to LEAVE by setting
index=limit which is not the case of F83. Also, LEAVE was defined as
immediate, exiting the loop entirely. As to how to change it, since I'm
replying online, I'll have to think about it...


Mon, 17 Nov 1997 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. first tiny not work

2. Why Forth is not doing so well

3. Does the Autosave works in Excel , if not how to make it work in my program

4. Why drawinto not working with Windows?

5. Why does it work sometimes but not always?

6. why my printer does not work?

7. Why is developer exchange not working for me?

8. Why does this Query not work

9. why do not works?

10. Why does one form work yet the other does not

11. why does this routine not work

12. Please help, why does this not work ?

 

 
Powered by phpBB® Forum Software