EPR experiment simulator in Forth

65 views
Skip to first unread message

Krishna Myneni

unread,
Aug 29, 2021, 10:22:37 PMAug 29
to
A preliminary version of a simulator for the Einstein-Podolsky-Rosen
experiment, written in Forth, may be found at the link below. It runs as
is under kForth-64 (please use latest development version, or update the
mini-oof.4th file from the kForth-64 repo). It also runs under Gforth
with a minimal, and mostly obvious, set of compatibility definitions,
below. Please see notes in the source for use with Gforth.

For those who are interested in this program, but not familiar with the
EPR thought experiment, please see the source, Refs. 1--3. Currently,
the article may be freely downloaded from the publisher's page linked
for Ref. 1.

Ref. 2 discusses the modern version of the EPR experiment, which is
simulated in the Forth program. It may be downloaded from its link.

Ref. 3's link points to the publisher's page, from which it is not
freely downloadable.

Finally, another interesting and readable paper dealing with the subject
of this program may be downloaded from here:

https://hal.archives-ouvertes.fr/jpa-00220688/document

--
Krishna Myneni


https://github.com/mynenik/kForth-64/blob/master/forth-src/qm/epr-sim.4th



Compatibility definitions for Gforth:
---------
\ kforth-compat.fs
\
\ kForth compatibility defns. for gforth
\
\ Revised: 2021-08-26

utime 2constant start_time

base @
: deg>rad ( F: r1 -- r2 ) PI f* 180.0e0 f/ ;
: rad>deg ( F: r1 -- r2 ) 180.0e0 f* PI f/ ;
: fround>s ( F: r -- ) ( -- s ) fround f>s ;
: ftrunc>s ( F: r -- ) ( -- s ) ftrunc f>s ;
: allot? ( u -- a ) here swap allot ;
: 2+ 2 + ;
: 2- 2 - ;
: ms@ ( -- u ) utime start_time d- 1000 um/mod nip ;
: us2@ ( -- ud ) utime start_time d- ;
: usleep ( u -- ) 1000 / 1 max ms ;
: nondeferred ( -- ) ;

synonym a@ @
base !
---------


Krishna Myneni

unread,
Aug 30, 2021, 8:22:20 AMAug 30
to
On 8/29/21 9:22 PM, Krishna Myneni wrote:

> Compatibility definitions for Gforth:
> ---------
> \ kforth-compat.fs
> \
> \ kForth compatibility defns. for gforth
> \
> \ Revised: 2021-08-26
>
> utime 2constant start_time
>
> base @

Insert DECIMAL after the above line.

> : deg>rad ( F: r1 -- r2 ) PI f* 180.0e0 f/ ;
> : rad>deg ( F: r1 -- r2 ) 180.0e0 f* PI f/ ;
> : fround>s ( F: r -- ) ( -- s ) fround f>s ;
> : ftrunc>s ( F: r -- ) ( -- s ) ftrunc f>s ;
> : allot?  ( u -- a ) here swap allot ;
> : 2+  2 + ;
> : 2-  2 - ;
> : ms@ ( -- u )  utime start_time d- 1000 um/mod nip ;
> : us2@ ( -- ud ) utime start_time d- ;
> : usleep ( u -- ) 1000 / 1 max ms ;

The compatibility definition for kForth's USLEEP is a quick hack. MS
provides a delay in milliseconds, but it does not call the operating
system's sleep function. I don't know how to do the equivalent call to
USLEEP in Gforth, and, although it doesn't appear to make much
difference for the program mentioned here, in general MS is not a
substitute for putting the process to sleep.

> : nondeferred ( -- ) ;
>
> synonym a@ @
> base !
> ---------
>
>

KM

Anton Ertl

unread,
Aug 30, 2021, 10:56:26 AMAug 30
to
Krishna Myneni <krishna...@ccreweb.org> writes:
>> : usleep ( u -- ) 1000 / 1 max ms ;
>
>The compatibility definition for kForth's USLEEP is a quick hack. MS
>provides a delay in milliseconds, but it does not call the operating
>system's sleep function. I don't know how to do the equivalent call to
>USLEEP in Gforth, and, although it doesn't appear to make much
>difference for the program mentioned here, in general MS is not a
>substitute for putting the process to sleep.

Why do you think that Gforth's MS does not put the process to sleep?

[~:124110] time gforth -e "500 ms bye"

real 0m0.511s
user 0m0.008s
sys 0m0.004s

Looks to me like it slept for 500ms.

What does MS call? Let's see:

[~:124111] strace gforth -e "500 ms bye"
...
nanosleep({0, 500000000}, 0x7fffc81ff230) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER|SA_NODEFER, 0x7f6717ea00e0}, {0x412ab0, [], SA_RESTORER|SA_NODEFER, 0x7f6717ea00e0}, 8) = 0
exit_group(0) = ?
+++ exited with 0 +++

So MS calls nanosleep() on Gforth 0.7.

On development Gforth I see:

pselect6(0, NULL, NULL, NULL, {0, 499999838}, {NULL, 8}) = 0 (Timeout)

This is on Linux, other calls will be used on systems that do not have
these system calls.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2021: https://euro.theforth.net/2021

S Jack

unread,
Aug 30, 2021, 12:22:52 PMAug 30
to
On Monday, August 30, 2021 at 9:56:26 AM UTC-5, Anton Ertl wrote:
> So MS calls nanosleep() on Gforth 0.7.

Just curious. Does nonosleep put the program to sleep such that no Forth task
will run during the MS interval; something a multi-tasker needs to consider?
--
me

Anton Ertl

unread,
Aug 30, 2021, 12:53:10 PMAug 30
to
S Jack <sdwj...@gmail.com> writes:
>On Monday, August 30, 2021 at 9:56:26 AM UTC-5, Anton Ertl wrote:
>> So MS calls nanosleep() on Gforth 0.7.
>
>Just curious. Does nonosleep put the program to sleep such that no Forth task
>will run during the MS interval;

man nanosleep says:

|nanosleep() suspends the execution of the calling thread until either
|at least the time specified in *req has elapsed, or the delivery of a
|signal [...]

>something a multi-tasker needs to consider?

So yes, if you have several Forth tasks in an OS thread, you need to
use a different system call, e.g., pselect(). However, while
development Gforth uses pselect() and supports multi-tasking, it only
waits for the timeout (or signal) with pselect. I guess each task
gets its own thread.

Krishna Myneni

unread,
Aug 30, 2021, 3:12:25 PMAug 30
to
On 8/30/21 9:49 AM, Anton Ertl wrote:
> Krishna Myneni <krishna...@ccreweb.org> writes:
>>> : usleep ( u -- ) 1000 / 1 max ms ;
>>
>> The compatibility definition for kForth's USLEEP is a quick hack. MS
>> provides a delay in milliseconds, but it does not call the operating
>> system's sleep function. I don't know how to do the equivalent call to
>> USLEEP in Gforth, and, although it doesn't appear to make much
>> difference for the program mentioned here, in general MS is not a
>> substitute for putting the process to sleep.
>
> Why do you think that Gforth's MS does not put the process to sleep?
>

I did not look at the source code for Gforth's implementation of MS. In
kForth we found that we can use a polling loop to obtain higher
precision delays for MS, rather than using a call to put the process to
sleep. This is why we have a separate word, USLEEP.

For example, on the same system,

$ time kforth64 -e "500 ms bye"
Goodbye.

real 0m0.506s
user 0m0.503s
sys 0m0.003s

$ time ./gforth -e "500 ms bye"

real 0m0.515s
user 0m0.006s
sys 0m0.006s

$ time kforth64 -e "1000 ms bye"
Goodbye.

real 0m1.006s
user 0m1.002s
sys 0m0.003s

$ time ./gforth -e "10000 ms bye"

real 0m10.024s
user 0m0.004s
sys 0m0.003s

--
Krishna

Krishna Myneni

unread,
Aug 30, 2021, 3:14:40 PMAug 30
to
Sorry, I copied the wrong instance for the 10000 ms test for kForth. But
the result is unchanged.

$ time kforth64 -e "10000 ms bye"
Goodbye.

real 0m10.006s
user 0m9.997s
sys 0m0.001s

--
KM
Reply all
Reply to author
Forward
0 new messages