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

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
   (DefinedPredicateNode "loopy")
   (SatisfactionLink
      (SequentialAndLink
         (EvaluationLink (GroundedPredicateNode "scm:prt") (ListLink))
         (DefinedPredicateNode "loopy")
      )))

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

The above example should print

scheme@(guile-user)> (cog-evaluate! (DefinedPredicateNode "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 SatistfactionLink has no variables in it. In the general case, the tail call optimization cannot be performed.

See also