DefinedPredicateNode

From OpenCog
Jump to: navigation, search

A DefinedPredicateNode is a kind of PredicateNode that may be defined with the DefineLink. The sole reason for having this node type is to be able to instantly recognize when a defined node is being used (as otherwise, every atom would need to be looked up to see if it has an associated definition).

The PutLink also behaves a lot like an EvaluationLink, when it is used with DefinedPredicateNodes. See PutLink for an example.

Example - Numerical formula

The following shows how a DefinedPredicateNode can be used with a DefineLink and a PredicateFormulaLink to create a numerical formula

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

; Compute TV = (1-sA*sB, cA*cB)
(DefineLink
   (DefinedPredicate "my formula (1-sA*sB, cA*cB)")
   (PredicateFormula
      (Minus
         (Number 1)
         (Times
            (StrengthOf (Variable "$X"))
            (StrengthOf (Variable "$Y"))))
      (Times
         (ConfidenceOf (Variable "$X"))
         (ConfidenceOf (Variable "$Y"))))

The fully-worked example can be found in /examples/atomspace/formulas.scm tutorial.

Example - Recursive function

The following shows how a DefinedPredicateNode can be used to create a recursive function:

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

; Increment, print, sleep. After the 6th call, return false; else return true. 
(define  n 0)
(define (prt)
   (set! n (+ n 1))
   (format #t "call count ~a\n" n) (sleep 2)
   (if (< n 6) (stv 1 1) (stv 0 1)))

; A recursive loop, calls itself forever as long as prt returns 'true'
(DefineLink
   (DefinedPredicate "loopy")
   (SatisfactionLink
      (SequentialAnd
         (EvaluationLink (GroundedPredicate "scm:prt") (ListLink))
         (DefinedPredicate "loopy")
      )))

; Run the above.
(cog-evaluate! (DefinedPredicate "loopy"))

The above example should print

scheme@(guile-user)> (cog-evaluate! (DefinedPredicate "loopy"))
call count 1
call count 2
call count 3
call count 4
call count 5
call count 6
$2 = (stv 0 1)
scheme@(guile-user)>

The above is in fact tail-recursive, ad, for this example, the code WILL perform the tail-call optimizaion. However, the optimization can be performed only because this is a very special case: the SatisfactionLink has no variables in it. In the general case, the tail call optimization cannot be performed.

More examples

Additional examples can be found in the /examples/atomspace and the /examples/pattern-matcher directories.

See also