-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathbasic.v
More file actions
365 lines (329 loc) · 12 KB
/
basic.v
File metadata and controls
365 lines (329 loc) · 12 KB
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
(* In this file we realize the basic operational semantics for BTs as a
program specified in the Gallina language. In other words, we define a
shallow embedding of the BT language in the type theory used by Coq. *)
Require Import Arith.
Require Import bt.
(* Version for BTs with binary nodes only. *)
Module BT_bin_semantics (X: BT_SIG).
Include BT_binary X.
Inductive return_enum := Runn | Fail | Succ.
Definition skills_input := X.skillSet -> return_enum.
(* A term of this type encapsulates a return value for each skill
at the instant of time in which the tick is executed. *)
Fixpoint tick (t: btree) (input_f: skills_input) :=
match t with
| Skill s => input_f s
| TRUE => Succ
| Node k _ t1 t2 => match k with
| Sequence =>
match (tick t1 input_f) with
| Runn => Runn
| Fail => Fail
| Succ => (tick t2 input_f)
end
| Fallback =>
match (tick t1 input_f) with
| Runn => Runn
| Fail => (tick t2 input_f)
| Succ => Succ
end
| Parallel1 =>
let a := tick t1 input_f in
let b := tick t2 input_f in
match a , b with
| Succ , _ => Succ
| _ , Succ => Succ
| Fail , Fail => Fail
| _ , _ => Runn
end
| Parallel2 =>
let a := tick t1 input_f in
let b := tick t2 input_f in
match a , b with
| Succ , Succ => Succ
| Fail , _ => Fail
| _ , Fail => Fail
| _ , _ => Runn
end
end
| Dec k _ t => match k with
| Not =>
match (tick t input_f) with
| Runn => Runn
| Fail => Succ
| Succ => Fail
end
| IsRunning =>
match (tick t input_f) with
| Runn => Succ
| Fail => Fail
| Succ => Fail
end
end
end.
Definition return_same_value (a: btree) (b: btree): Prop :=
forall i: skills_input, (tick a i) = (tick b i).
(* Proof of a simple result concerning associativity of binary nodes *)
Theorem all_nodes_are_associative:
forall k: nodeKind,
forall s s' s'': String.string,
forall c_1 c_2 c_3: btree,
let a := (Node k s (Node k s' c_1 c_2) c_3) in
let b := (Node k s c_1 (Node k s'' c_2 c_3)) in
return_same_value a b.
Proof.
unfold return_same_value.
intros.
induction k.
- simpl.
destruct (tick c_1); auto.
- simpl.
destruct (tick c_1); auto.
- simpl.
destruct (tick c_1); destruct (tick c_2); destruct (tick c_3); auto.
- simpl.
destruct (tick c_1); destruct (tick c_2); destruct (tick c_3); auto.
Qed.
End BT_bin_semantics.
(* Version for BTs with arbitrary branching. *)
Module BT_gen_semantics (X: BT_SIG).
Include BT_general X.
Inductive return_enum := Runn | Fail | Succ.
Definition skills_input := X.skillSet -> return_enum.
(* A term of this type encapsulates a returns value for each skill
at the instant of time in which the tick is executed. *)
Fixpoint countSucc (l: list return_enum) :=
match l with
| nil => 0
| cons head tail => match head with
| Succ => S (countSucc tail)
| _ => countSucc tail
end
end.
Fixpoint countFail (l: list return_enum) :=
match l with
| nil => 0
| cons head tail => match head with
| Fail => S (countFail tail)
| _ => countFail tail
end
end.
Fixpoint tick (t: btree) (input_f: skills_input) :=
match t with
| Skill s => input_f s
| TRUE => Succ
| Node k _ f => match k with
| Sequence => tick_sequence f input_f
| Fallback => tick_fallback f input_f
| Parallel n =>
let results := tick_all f input_f in
if n <=? (countSucc results) then Succ
else if (len f - n) <? (countFail results) then Fail
else Runn
end
| Dec k _ t => match k with
| Not =>
match tick t input_f with
| Runn => Runn
| Fail => Succ
| Succ => Fail
end
| IsRunning =>
match tick t input_f with
| Runn => Succ
| Fail => Fail
| Succ => Fail
end
end
end
with tick_sequence (f: btforest) (input_f: skills_input) :=
match f with
| Child t => tick t input_f
| Add t1 rest => match tick t1 input_f with
| Runn => Runn
| Fail => Fail
| Succ => tick_sequence rest input_f
end
end
with tick_fallback (f: btforest) (input_f: skills_input) :=
match f with
| Child t => tick t input_f
| Add t1 rest => match tick t1 input_f with
| Runn => Runn
| Fail => tick_fallback rest input_f
| Succ => Succ
end
end
with tick_all (f: btforest) (input_f: skills_input) :=
match f with
| Child t => cons (tick t input_f) nil
| Add t1 rest => cons (tick t1 input_f) (tick_all rest input_f)
end.
(* As an application, we prove that applying the normalize function
to a BT does not alter its return value. *)
Definition return_same_value (t1 t2: btree) :=
forall i: skills_input, (tick t1 i) = (tick t2 i).
Fixpoint all_return_same_value (f1 f2: btforest) :=
match f1, f2 with
| Child t1, Child t2 => return_same_value t1 t2
| Child t1, Add t2 r2 => False
| Add t1 r1, Child t2 => False
| Add t1 r1, Add t2 r2 => return_same_value t1 t2
/\ all_return_same_value r1 r2
end.
Hint Unfold return_same_value all_return_same_value.
Lemma norm_seq: forall f: btforest,
all_return_same_value f (normalize_forest f)
-> forall i: skills_input,
tick_sequence f i = tick_sequence (normalize_forest f) i.
Proof.
apply (btforest_mind
(fun bt: btree => return_same_value bt (normalize bt)
-> forall i: skills_input, tick bt i = tick (normalize bt) i)
(fun f: btforest => all_return_same_value f (normalize_forest f)
-> forall i: skills_input, tick_sequence f i = tick_sequence (normalize_forest f) i)).
- simpl; auto.
- simpl; auto.
- simpl; auto.
- simpl; auto.
- simpl.
intros t H H0 i.
rewrite (H H0 i); trivial.
- simpl.
intros t Ht f Hf.
intros [H0 H1] i.
rewrite (Ht H0); rewrite (Hf H1); trivial.
Qed.
Lemma norm_fall: forall f: btforest,
all_return_same_value f (normalize_forest f)
-> forall i: skills_input,
tick_fallback f i = tick_fallback (normalize_forest f) i.
Proof.
apply (btforest_mind
(fun bt: btree => return_same_value bt (normalize bt)
-> forall i: skills_input, tick bt i = tick (normalize bt) i)
(fun f: btforest => all_return_same_value f (normalize_forest f)
-> forall i: skills_input, tick_fallback f i = tick_fallback (normalize_forest f) i)).
- simpl; auto.
- simpl; auto.
- simpl; auto.
- simpl; auto.
- simpl.
intros t H H0 i.
rewrite (H H0 i); trivial.
- simpl.
intros t Ht f Hf.
intros [H0 H1] i.
rewrite (Ht H0); rewrite (Hf H1); trivial.
Qed.
Lemma normalize_preserves_length:
forall f: btforest, len (normalize_forest f) = len f.
Proof.
induction f.
- auto.
- simpl; f_equal; assumption.
Qed.
Lemma norm_par: forall f: btforest,
all_return_same_value f (normalize_forest f)
-> forall i: skills_input,
tick_all f i = tick_all (normalize_forest f) i.
Proof.
apply (btforest_mind
(fun bt: btree => return_same_value bt (normalize bt)
-> forall i: skills_input, tick bt i = tick (normalize bt) i)
(fun f: btforest => all_return_same_value f (normalize_forest f)
-> forall i: skills_input, tick_all f i = tick_all (normalize_forest f) i)).
- simpl; auto.
- simpl; auto.
- simpl; auto.
- simpl; auto.
- simpl.
intros t H H0 i.
rewrite (H H0 i); trivial.
- simpl.
intros t Ht f Hf.
intros [H0 H1] i.
rewrite (Ht H0); rewrite (Hf H1); trivial.
Qed.
Lemma normalize_preserves_node:
forall (k: nodeKind) (s: String.string) (f: btforest),
all_return_same_value f (normalize_forest f) ->
return_same_value (Node k s f) (normalize (Node k s f)).
Proof.
induction k.
(* sequence case *)
+ destruct f.
-- simpl; auto.
-- simpl.
intros [H H0] i.
simpl.
assert (H1: tick b i = tick (normalize b) i) by (apply H).
assert (H2: tick_sequence f i = tick_sequence (normalize_forest f) i) by (apply norm_seq; assumption).
rewrite H1; rewrite H2; trivial.
(* fallback case *)
+ destruct f.
-- simpl; auto.
-- simpl.
intros [H H0] i.
simpl.
assert (H1: tick b i = tick (normalize b) i) by (apply H).
assert (H2: tick_fallback f i = tick_fallback (normalize_forest f) i) by (apply norm_fall; assumption).
rewrite H1; rewrite H2; trivial.
(* parallel case *)
+ destruct f.
-- simpl.
intros H i.
simpl; rewrite H; auto.
-- simpl.
intros [H H0] i.
unfold return_same_value in H.
simpl.
rewrite (H i).
rewrite (norm_par f H0 i).
rewrite (normalize_preserves_length f).
trivial.
Qed.
Lemma normalize_preserves_decs:
forall (d: decKind) (s: String.string) (t: btree),
return_same_value t (normalize t) ->
return_same_value (Dec d s t) (normalize (Dec d s t)).
Proof.
induction d.
(* not case *)
+ intros s t H i.
simpl.
destruct t.
-- simpl; auto.
-- simpl; auto.
-- rewrite (H i); simpl.
destruct n; simpl in H; rewrite <- H; trivial.
-- destruct d.
++ simpl.
destruct (tick t i); simpl; trivial.
++ rewrite (H i).
simpl; trivial.
(* isrunning case*)
+ intros s t H i.
simpl; rewrite H; trivial.
Qed.
Theorem normalize_preserves_return_value:
forall t: btree, return_same_value t (normalize t).
Proof.
apply (btree_mind
(fun bt: btree => return_same_value bt (normalize bt))
(fun f: btforest => all_return_same_value f (normalize_forest f))).
- simpl; auto.
- simpl; auto.
- apply normalize_preserves_node.
- apply normalize_preserves_decs.
- destruct b; simpl; auto.
- destruct b; simpl; auto.
Qed.
End BT_gen_semantics.
(* Program extraction for the behavior tree interpreter *)
Require Import Extraction.
Require ExtrOcamlBasic ExtrOcamlString.
Extract Inductive nat => "int" ["0" "succ"]
"(fun fO fS n -> if n=0 then fO () else fS (n-1))".
Extract Constant plus => "( + )".
Extraction "infra/btsem.ml" BT_gen_semantics.