OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / examples / query / presence.scm

142 lines · scm ref:
;;
;; presence.scm -- Testing for the presence of an Atom.
;;
;; Four different ways to check for the existence of some structure
;; in the AtomSpace.
;;
;; Each variant checks to see if the AtomSpace contains the link
;;    (ListLink (AnchorNode "Room State") (ConceptNode "room empty"))
;;
;; If the AtomSpace does contain the above, then the print-msg function
;; is run. Each different method has its strengths and weaknesses.
;; Several of the methods are good for designing behavior trees that
;; run inside the AtomSpace.  Others fit the more traditional query
;; paradigm.

(use-modules (opencog))

;; Is the room empty, or is someone in it?
;; One of several different states can be linked to the state variable.
(define room-state (Anchor "Room State"))
(define room-empty (Concept "room empty"))
(define room-nonempty (Concept "room nonempty"))

;; Assume room empty at first
(List room-state room-empty)

; Print a message, return a TV value
(define (tv-print-msg)
	(display "Hello, I've been triggered!\n") #t)

; Print an atom, return a TV value
(define (tv-print-atom atom)
	(format #t "Hello, I got this atom: ~a\n" atom) #t)

; Print an Atom, return an Atom.
(define (atom-print-atom atom)
	(format #t "Hello, Executing with atom: ~a\n" atom) atom)

; ------------------------------------------------------
; ------------------------------------------------------

;; This variant uses PresentLink to place the room-state into
;; a variable, and then uses EqualLink to check the value of
;; that variable.
;;
;; This variant has an advantage over the next one, as it requires
;; only one invocation of the pattern matcher, not two. Because it
;; uses the SequentialAndLink, it is in a form appropriate for creating
;; a behavior tree.
;;
;; Note that there may be other atoms linked to the Anchor;
;; it there are, then those other atoms are ignored. This may be
;; an advantage or a disadvantage; the next example demands that
;; there be only one atom linked to the Anchor.
;;
(define empty-sequence
	(Satisfaction
		;; SequentialAndLink - verify predicates in sequential order.
		(SequentialAnd
			;; Assign the room-state to variable $x
			;; PresentLink evaluates to 'true' if the ListLink is found;
			;; processing continues to the next statement ONLY if true
			;; is returned by the PresentLink.
			(Present (List room-state (Variable "$x")))
			;; If the variable $x equals the empty state, then ...
			(Equal (Variable "$x") room-empty)
			;; ... then print a message.
			(Evaluation
				(GroundedPredicate "scm: tv-print-atom")
				(List (Variable "$x")))
		)))

(cog-execute! empty-sequence)

; ------------------------------------------------------
;; This variant uses a MeetLink to fetch the room-state from the
;; AtomSpace, and then uses EqualLink to see if it is in the desired
;; state. Note that this results in *two* invocations of the pattern
;; matcher; the MeetLink being the inner one.  Note also that the
;; MeetLink returns it's results in a UnisetValue, which is wrapped
;; by CollectionOf to convert it to a SetLink for the equality comparison.
;;
;; In this example, the variable $x is bound by the MeetLink, and
;; is thus not available outside of the MeetLink.  Thus, the grounding
;; for that variable cannot be given to the print-message routine.
;;
;; Unlike the previous example, this one will explicitly fail if there
;; are other atoms linked to the Anchor.  That is, the equality
;; check is making sure that the UnisetValue has one and only one element
;; in it, which effectively blocks other anchored atoms.  This may be
;; an advantage, or a disadvantage, depending on the situation.

(define get-empty-seq
	(Satisfaction
		;; Perform operations in sequential order.
		(SequentialAnd
			;; Check for equality ...
			(Equal
				(Set room-empty)
				;; Retrieve the room state; place it into a SetLink
				(CollectionOf (Meet (List room-state (Variable "$x")))))

			;; If the EqualLink evaluated to TRUE, then print the message.
			(Evaluation
				(GroundedPredicate "scm: tv-print-msg")
				(List))  ; zero arguments passed to function
		)))

(cog-execute! get-empty-seq)

; ------------------------------------------------------
;; This variant uses the traditional QueryLink format to trigger
;; the execution of a schema.  It is similar to the first example,
;; except for these notable differences:
;;
;; -- The QueryLink does not use SequentialAnd, and thus any embedded
;;    GPN may or may not run after the EqualLink; there is no guarantee
;;    of ordered execution.
;; -- The action to be performed must be in the form of a GSN, and thus
;;    it must return an atom, not a truth value.
;; -- Because of the above, actions cannot be chained: this is not
;;    suitable for creating a behavior tree.

(define bind-empty
	(Query
		;; Perform operations in sequential order.
		(And
			;; Assign the room-state to variable $x
			(List room-state (Variable "$x"))
			;; If the variable $x equals the empty state, then ...
			(Equal (Variable "$x") room-empty)
		)
		;; If the EqualLink evaluated to TRUE, then print the message.
		(ExecutionOutput
				(GroundedSchema "scm: atom-print-atom")
				(List (Variable "$x")))
		))

(cog-execute! bind-empty)

; ------------------------------------------------------