-
Notifications
You must be signed in to change notification settings - Fork 234
/
sequence.scm
139 lines (123 loc) · 4.26 KB
/
sequence.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
;
; sequence.scm -- Behavior sequences
;
; Demonstrate using behavior trees to interact with external systems,
; such as robots or game worlds. Behavior trees (see Wikipedia:
; https://en.wikipedia.org/wiki/Behavior_tree_(artificial_intelligence,_robotics_and_control)
; are commonly used in game worlds to control non-player characters
; and to perform AI stimulus-response action sequences ("SRAI").
;
; The SatisfactionLink, combined with the SequentialAndLink, implements
; the concept of a behavior tree "sequence node", and so writing
; behavior trees in Atomese is straight-forward. (See also ParallelLink
; and JoinLink for general scripting in multiple threads).
;
; Interacting with external systems in Atomese can be accomplished with
; GroundedPredicateNode and with GroundedSchemaNode. This example
; demonstrates how behavior scripting can be used to obtain input from
; external systems.
;
; This example uses the GroundedPredicateNode to provide a simple
; behavior sequence: i.e. a set of steps that are conditionally played
; out, depending on whether the predicate returns true of false.
; There are no variables in this demo; thus, the sequence is not
; a graph search, but is rather a straight-forward if-else sequence
; evaluation.
;
; This demo also demonstrates the use of a SatisfactionLink: there is no
; output, and no graph-rewriting occurs, thus a BindLink is not needed,
; and the simpler SatisfactionLink is enough.
;
;
(use-modules (opencog) (opencog exec))
(define green-light (Concept "green light"))
(define red-light (Concept "red light"))
; Counts of how many times the green and red lights were seen.
(define num-green 0)
(define num-red 0)
; Return SimpleTruthValue of true if green light, false if red light,
; and throw an exception if neither. Increment counters so that we
; can verify that this was invoked.
(define (stop-go atom)
(format #t "Got called with this: ~A\n" (cog-name atom))
(cond
((equal? atom green-light) (begin (set! num-green (+ 1 num-green)) (stv 1 1)))
((equal? atom red-light) (begin (set! num-red (+ 1 num-red)) (stv 0 1)))
(else (throw 'not-a-stoplight "stop-go" "you're busted"))
)
)
; Should throw an exception in all cases. Shouldn't do donuts on
; corn fields.
(define off-road
(Satisfaction
(VariableList) ; no variables
(SequentialAnd
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List (Concept "corn field"))))))
;; Should see two green lights, and one red light, after which
;; the matching should stop. There should be no exceptions or
;; errors when evaluating this.
(define traffic-lights
(Satisfaction
(VariableList) ; no variables
(SequentialAnd
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List green-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List green-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List red-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List (Concept "traffic ticket"))))))
(define (start-again)
(cog-evaluate! traffic-lights)
(format #t "Have seen ~A green lights and ~A red lights\n"
num-green num-red))
;;; Try the below. This should result in an exception being thrown.
;;;
; (cog-evaluate! off-road)
;
;;; The below should result in the green light being seen twice, and
;;; the red light once, and no exceptions or errors.
;;;
; (start-again)
; (start-again)
; (start-again)
;
;
;;; The below is very similar to the above, except that this uses
;;; a SequentialOrLink that halts after the first TRUE value.
;;;
(define hot-rodding
(Satisfaction
(VariableList) ; no variables
(SequentialOr ; <==== unlike before, this is OR
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List red-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List red-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List red-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List green-light))
(Evaluation
(GroundedPredicateNode "scm: stop-go")
(List (Concept ".... And they're off!"))))))
(define (drag-race)
(cog-evaluate! hot-rodding)
(simple-format #t "Waited on ~A red lights\n" num-red))
;;; The below should result in the three red lights before it turns
;;; green.
;;;
; (drag-race)
; (drag-race)
; (drag-race)