<commit_before>;
; parallel.scm -- Multi-threading in Atomese
;
; Running programs and loops and what-not in Atomese can be awkward
; if you can't run things in parallel. Ah hah! But you can! The
; ParallelLink and the JoinLink allow threads to be created and joined.
;

(use-modules (opencog) (opencog exec))

; Define a simple counter that will be incremented
(define (make-counter)
	(let ((nnn 1))
		(lambda ()
			(format #t "Entering the counter for the ~A'th time!\n" nnn)
			(format #t " -- The time is ~A\n"
				(strftime "%c" (localtime (current-time))))
			(set! nnn (+ nnn 1))
			(stv 1 0))
	))

(define incr (make-counter))

; Define a dettached thread
(define pllel
	(Parallel
		(SequentialAnd
			(True (Sleep (Number 1)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 3)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 5)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
	))

(define wait
	(Join
		(SequentialAnd
			(True (Sleep (Number 1)))
			(EvaluationLink
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(False (Sleep (Number 3)))
			(EvaluationLink
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 5)))
			(EvaluationLink
				(GroundedPredicate "scm:incr") (List)))
	))<commit_msg>Add an explanation of what is going on.<commit_after>;
; parallel.scm -- Multi-threading in Atomese
;
; Running programs and loops and what-not in Atomese can be awkward
; if you can't run things in parallel. Ah hah! But you can! The
; ParallelLink and the JoinLink allow threads to be created and joined.
;

(use-modules (opencog) (opencog exec))

; Define a simple counter that will be incremented
(define (make-counter)
	(let ((nnn 1))
		(lambda ()
			(format #t "Finished running the thread; exiting!\n")
			(format #t " -- This is the ~A'th we've finished!\n" nnn)
			(format #t " -- The time is ~A\n\n"
				(strftime "%c" (localtime (current-time))))
			(set! nnn (+ nnn 1)) ; This increment is not thread-safe!
			(stv 1 0))
	))

(define incr (make-counter))

; Define three dettached threads. When this is evaluated, the
; ParallelLink will create three dettached threads, one for each
; Atom in it's outgoing set. (One thread for each SequentialAndLink).
; It will then return immediately to the caller.  Meanwhile, each thread
; will go off and do it's thing. The three threads will each sleep
; a varying amount, and print a message when they are done.
(define pllel
	(Parallel
		(SequentialAnd
			(True (Sleep (Number 1)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 3)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 5)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
	))

; So create the thread, and run it.
(cog-evaluate! pllel)

; And again, just for good luck!
(cog-evaluate! pllel)

; This is almost identical to the above, except that the JoinLink
; will not return control to the evaluator until all of the threads
; have finished. The longest running thread takes five seconds, so
; sit back and relax and watch the pretty messages appear.
(define wait
	(Join
		(SequentialAnd
			(True (Sleep (Number 1)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 3)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
		(SequentialAnd
			(True (Sleep (Number 5)))
			(Evaluation
				(GroundedPredicate "scm:incr") (List)))
	))

; Wait for the threads to finish.
(cog-evaluate! wait)
(cog-evaluate! wait)
(cog-evaluate! wait)
{'fraction_non_alphanumeric': 0.12486457204767064, 'fraction_numerical': 0.005417118093174431, 'mean_word_length': 3.8656126482213438, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7225264', 'n_tokens_mistral': 1417, 'n_tokens_neox': 1226, 'n_words': 453}