OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / tests / atoms / random-choice.scm

99 lines · scm ref:
;
; Unit test for several different things, that are not really
; tested anywhere else (or are poorly tested):
; -- RandomChoiceLink with weights
; -- DefinedPredicate and DefinedProcedure
; -- DivideLink
; -- Tail recursion optimization in the SequentialAndLink
; -- Lazy/Eager execution of FunctionLink arguments.
;
(use-modules (opencog))

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

; Pick A with 70% probability, pick B with 30% probability.
(Define (DefinedProcedure "rand-set-choice")
   (RandomChoice
      (SetLink
         (List (Number 0.7) (Concept "A"))
         (List (Number 0.3) (Concept "B")))))

; Pick A with 70% probability, pick B with 30% probability.
; Use a MeetLink to fish out the probabilities, instead of
; hard-coding them, as above. This forces the lazy/eager
; evaluation subsystem to "do the right thing" -- to evaluate
; the MeetLink before running the RandomChoice.
(Define (DefinedProcedure "randy")
   (RandomChoice
      (MeetLink
         (VariableList (VariableNode "$prob") (VariableNode "$expr"))
         (AndLink
            (EvaluationLink
               (PredicateNode "Emotion-expression")
               (ListLink (ConceptNode "wake-up") (VariableNode "$expr")))
            (StateLink
               (ListLink
                  (ConceptNode "wake-up")
                  (VariableNode "$expr"))
               (VariableNode "$prob"))))
      ))

; Data to allow the MeetLink above to find the needed data.
(Evaluation (Predicate "Emotion-expression")
   (ListLink (Concept "wake-up") (Concept "A")))
(State (ListLink (ConceptNode "wake-up") (Concept "A")) (Number 0.7))

(Evaluation (Predicate "Emotion-expression")
   (ListLink (Concept "wake-up") (Concept "B")))
(State (ListLink (ConceptNode "wake-up") (Concept "B")) (Number 0.3))

; 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
         (Equal (DefinedProcedure "randy") (Concept "A"))
         (True (Put
            (State (Anchor "sum-A") (Variable "$x"))
            (Plus (Number 1)
               (Meet (State (Anchor "sum-A") (Variable "$y")))))))
      (True (Put
         (State (Anchor "sum-B") (Variable "$x"))
         (Plus (Number 1)
            (Meet (State (Anchor "sum-B") (Variable "$y"))))))))

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

(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 3000)
         (Meet (State (Anchor "loop-count") (Variable "$x"))))
      (DefinedPredicate "loop a lot of times")))

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

; Expectation value is 0.7/0.3 = 2.33333
(Define (DefinedPredicate "test")
   (SequentialAnd
      (GreaterThan (Number 2.5) (DefinedProcedure "ratio"))
      (GreaterThan (DefinedProcedure "ratio") (Number 2.2))))

*unspecified*