-
Notifications
You must be signed in to change notification settings - Fork 234
/
fsm-full.scm
142 lines (130 loc) · 3.35 KB
/
fsm-full.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
;
; fsm-full.scm -- Finite State Machine (FSM) Demo.
;
; Based on `fsm-basic.scm`, this defines a very simple four-state finite
; state machine, but illustrates the general (universal) FSM state
; machine constructor. This allows multiple FSM's to be simultaneously
; defined and operated asynchronously from each-other.
;
(use-modules (opencog))
;; Set of possible states of the state machine
;; This definition of the set of states is not strictly needed; it is
;; not used anywhere in the demo below.
(SetLink
(ConceptNode "initial state")
(ConceptNode "green")
(ConceptNode "yellow")
(ConceptNode "red")
)
(define my-trans (Concept "My FSM's Transition Rule"))
(define my-state (Anchor "My FSM's Current State"))
;; The initial state of the FSM
(List
my-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).
;;
;; Each rule is labelled with the "my-trans", so that rules for
;; different FSM's do not clash with one-another. A ContextLink is used
;; because that will allow this example to generalize: Context's are
;; usually used to express conditional probabilities, so that
;;
;; Context <TV>
;; A
;; B
;;
;; represents the probability of B conditioned on A, and the TV holds
;; the numeric value for P(B|A). In this case, A is the current state
;; of the machine, and B the the next state of the machine, so that P(B|A)
;; is the probability of transitioning to state B give that the machine is
;; in state A. Such a system is called a Markov Chain.
;;
;; For the example below, P(B|A) is always one.
(ContextLink
(Concept "initial state")
(List
my-trans
(Concept "green")
)
)
(ContextLink
(Concept "green")
(List
my-trans
(Concept "yellow")
)
)
(ContextLink
(Concept "yellow")
(List
my-trans
(Concept "red")
)
)
(ContextLink
(Concept "red")
(List
my-trans
(Concept "green")
)
)
;;; A Universal Deterministic Finite State Machine Constructor.
;;;
;;; This will create a deterministic FSM; that is, a rule that will
;;; transition any arbitrary deterministic FSM from state to state,
;;; given only its name, and the name given to the transition rules.
;;;
;;; Create a BindLink that can take an FSM with the name `fsm-name`
;;; and stores it's state in `fsm-state`. After the BindLink is
;;; created, each invocation of it will advance the FSM but one step.
;;;
(define (create-fsm fsm-name fsm-state)
(Bind
;; 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
fsm-state
(Variable "$curr-state")
)
;; ... and there is a transition to another state...
(Context
(Variable "$curr-state")
(List
fsm-name
(Variable "$next-state")
)
)
)
(And
;; ... then transition to the next state ...
(List
fsm-state
(Variable "$next-state")
)
;; ... and leave the current state.
(Delete
(List
fsm-state
(Variable "$curr-state")
)
)
)
)
)
;;; Create "my-fsm"
(define my-fsm (create-fsm my-trans my-state))
;;; Take one step.
;(cog-execute! my-fsm)
;;; Take three steps.
;;; Try it!
;(cog-execute! my-fsm)
;(cog-execute! my-fsm)
;(cog-execute! my-fsm)