OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / examples / query / fsm-basic.scm

111 lines · scm ref:
;
; fsm-basic.scm -- Very Simple Finite State Machine (FSM) Demo.
;
; This defines a very simple four-state finite state machine: an initial
; state, and a cycle of three state: green, yellow, red. It then uses a
; QueryLink to take one step at a time.  The QueryLink is more or less
; "universal", in that it can run any FSM, not  just this one. However,
; here it has been a bit simplified, to keep the demo as simple as
; possible. See the file `fsm-full.scm` for the correct way to define a
; truly general-purpose FSM, in such a way that multiple FSM's can be run
; at the same time.
;
(use-modules (opencog))

;; Set of possible states of the state machine.
;; The definition of this set is not strictly needed; it is not used
;; for anything in the demo code below.
(Set
	(Concept "initial state")
	(Concept "green")
	(Concept "yellow")
	(Concept "red")
)

;; The initial state of the FSM
(List
	(Anchor "Current State")
	(Concept "initial state")
)

;; The set of allowed state transitions.  Its a triangular cycle,
;; of green going to yellow going to red going back to green.
;; The initial state transitions into green (and is never visited again).
(List
	(Concept "initial state")
	(Concept "green")
)

(List
	(Concept "green")
	(Concept "yellow")
)

(List
	(Concept "yellow")
	(Concept "red")
)

(List
	(Concept "red")
	(Concept "green")
)


;;; Take one step of a finite state machine.
;;; Note that the algorithm below is "universal": it can run any FSM,
;;; it does not care about the specific states or state transition
;;; rules.
;;;
;;; To define two or more machines that run at the same time, each
;;; should use a different AnchorNode, so that the states of the
;;; various machines would not get confused with one-another.
;;; It would also probably be a good idea to include the machine name
;;; (i.e. the AnchorNode) as part of the transition rules, so that
;;; the transition rules for one machine would not get used accidentally
;;; for another machine.
(define take-one-step
	(Query
		;; We will need to find the current and the next state
		(VariableList
			(Variable "$curr-state")
			(Variable "$next-state")
		)
		(And
			;; If we are in the current state ...
			(List
				(Anchor "Current State")
				(Variable "$curr-state")
			)
			;; ... and there is a transition to another state...
			(List
				(Variable "$curr-state")
				(Variable "$next-state")
			)
		)
		(And
			;; ... then transition to the next state ...
			(List
				(Anchor "Current State")
				(Variable "$next-state")
			)
			;; ... and leave the current state.
			(Delete
				(List
					(Anchor "Current State")
					(Variable "$curr-state")
				)
			)
		)
	)
)

;; Take on step of the FSM
;(cog-execute! take-one-step)
;
;;; Take three more steps;
;;; Try it!  See what happens!
;(cog-execute! take-one-step)
;(cog-execute! take-one-step)
;(cog-execute! take-one-step)