forked from singnet/atomspace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfsm-full.scm
163 lines (149 loc) · 3.99 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
;
; 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 mutlple FSM's to be simultaneously
; defined and operated asynchronously from each-other.
;
; The run this, you probably need to do this:
;
; OCDIR=home/home/yourname/opencog
; export LTDL_LIBRARY_PATH=$OCDIR/build/opencog/guile:$OCDIR/build/opencog/query
;
; Add the following to your ~/.guile file:
; (add-to-load-path "/home/yourname/opencog/build")
; (add-to-load-path "/home/yourname/opencog/opencog/scm")
; (add-to-load-path ".")
;
; Start guile:
; guile
;
; and then load this file:
; (load-from-path "fsm-full.scm")
;
; Then, scroll to the bottom, and try some of the commented-out
; examples.
(use-modules (opencog))
(use-modules (opencog query))
;; Set of possible states of the state machine
;; This defintion 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 (ConceptNode "My FSM's Transition Rule"))
(define my-state (AnchorNode "My FSM's Current State"))
;; The inital state of the FSM
(ListLink
my-state
(ConceptNode "initial state")
)
;; The set of allowed state transistions. Its a triangular cycle,
;; of green goint to yellow going to red going back to green.
;; The intial state transitions into green (and is never visted again).
;;
;; Each rule is labelled with the "my-trans", so that rules for
;; different FSM's do not clash with one-another. A ConextLink 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
;;
;; representes the probibility of B contiditoned 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 theh 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
(ConceptNode "initial state")
(ListLink
my-trans
(ConceptNode "green")
)
)
(ContextLink
(ConceptNode "green")
(ListLink
my-trans
(ConceptNode "yellow")
)
)
(ContextLink
(ConceptNode "yellow")
(ListLink
my-trans
(ConceptNode "red")
)
)
(ContextLink
(ConceptNode "red")
(ListLink
my-trans
(ConceptNode "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 bu one step.
;;;
(define (create-fsm fsm-name fsm-state)
(BindLink
;; We will need to find the current and the next state
(VariableList
(VariableNode "$curr-state")
(VariableNode "$next-state")
)
(AndLink
;; If we are in the current state ...
(ListLink
fsm-state
(VariableNode "$curr-state")
)
;; ... and there is a transition to another state...
(ContextLink
(VariableNode "$curr-state")
(ListLink
fsm-name
(VariableNode "$next-state")
)
)
)
(AndLink
;; ... then transistion to the next state ...
(ListLink
fsm-state
(VariableNode "$next-state")
)
;; ... and leave the current state.
(DeleteLink
(ListLink
fsm-state
(VariableNode "$curr-state")
)
)
)
)
)
;;; Create "my-fsm"
(define my-fsm (create-fsm my-trans my-state))
;;; Take one step.
;(cog-bind-single my-fsm)
;;; Take three steps.
;;; Try it!
;(cog-bind-single my-fsm)
;(cog-bind-single my-fsm)
;(cog-bind-single my-fsm)