OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / examples / atomspace / random-choice.scm

94 lines · scm ref:
;
; random-choice.scm -- Using the RandomChoiceLink for sampling.
;
; This example uses the RandomChoiceLink to pick one of two alternatives,
; ConceptNode A or ConceptNode B, with a probability of 70-30.  It then
; counts how often each of these choices occurred.
;
(use-modules (opencog))

; Pick A with 70% probability, pick B with 30% probability.
(Define (DefinedProcedure "randy")
	(RandomChoice
		(List (Number 0.7) (Number 0.3))
		(List (Concept "A") (Concept "B"))))

; Initialize counts to zero.
(State (Anchor "sum-A") (Number 0))
(State (Anchor "sum-B") (Number 0))

; Accumulate counts of how often A and B are picked.
(Define (DefinedPredicate "counter")
	(SequentialOr
		(SequentialAnd
			; If A was picked...
			(Equal (DefinedProcedure "randy") (Concept "A"))
			; ... then increment the count of A ...
			(True (Put
				(State (Anchor "sum-A") (Variable "$x"))
				(Plus (Number 1)
					(Meet (State (Anchor "sum-A") (Variable "$y")))))))
		; ... else increment the count of B.
		(True (Put
			(State (Anchor "sum-B") (Variable "$x"))
			(Plus (Number 1)
				(Meet (State (Anchor "sum-B") (Variable "$y"))))))))

; Run this several times.
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))
(cog-execute! (DefinedPredicate "counter"))

; Print the counts.
(cog-execute! (Meet (State (Anchor "sum-A") (Variable "$x"))))
(cog-execute! (Meet (State (Anchor "sum-B") (Variable "$x"))))

; Run it a thousand times.
(State (Anchor "loop-count") (Number 0))

; This defines a tail-recursive loop. The loop-counter is incremented,
; and, if it is less than a thousand, the function calls itself again.
(Define (DefinedPredicate "loop a lot of times")
	(SequentialAnd
		(DefinedPredicate "counter")
		(TrueLink (PutLink
			(State (Anchor "loop-count") (Variable "$x"))
			(Plus (Number 1) (Meet (State (Anchor "loop-count") (Variable "$x"))))))
		(GreaterThan
			(Number 1000)
			(Meet (State (Anchor "loop-count") (Variable "$x"))))
		(DefinedPredicate "loop a lot of times")))

; Actually execute the loop.
(cog-execute! (DefinedPredicate "loop a lot of times"))

; Print the counts again.
(cog-execute! (Meet (State (Anchor "sum-A") (Variable "$x"))))
(cog-execute! (Meet (State (Anchor "sum-B") (Variable "$x"))))

; Print the ratio.
(Define (DefinedProcedure "ratio")
	(Divide
		(Meet (State (Anchor "sum-A") (Variable "$x")))
		(Meet (State (Anchor "sum-B") (Variable "$x")))))

(cog-execute! (DefinedProcedure "ratio"))

; Test that the actual ratio is close to the expectation value.
; The expectation value is 0.7 / 0.3 = 2.33333 ...
; We should almost always, after a thousand times, get a ratio
; that is greater than 2.1 and less than 2.5.
(Define (DefinedPredicate "test expectation")
   (SequentialAnd
      (GreaterThan (Number 2.5) (DefinedProcedure "ratio"))
      (GreaterThan (DefinedProcedure "ratio") (NumberNode 2.1))))

(cog-execute! (DefinedPredicate "test expectation"))