-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgol_sim_okScript.sml
2325 lines (2164 loc) · 77.9 KB
/
gol_sim_okScript.sml
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
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(*
A formalisation of the rules of Conway's Game of Life (GOL).
*)
open HolKernel bossLib boolLib Parse;
open pred_setTheory pairTheory dep_rewrite arithmeticTheory listTheory
alistTheory rich_listTheory combinTheory gol_rulesTheory
gol_lemmasTheory gol_simTheory gol_circuitTheory gol_io_stepTheory;
val _ = new_theory "gol_sim_ok";
Overload LLOOKUP = “λl n. oEL n l”;
Overload "U" = “BIGUNION”;
Theorem MAP_EQ_ID:
∀f ls. MAP f ls = ls ⇔ ∀x. MEM x ls ⇒ f x = x
Proof
metis_tac [MAP_EQ_f,MAP_ID,combinTheory.I_THM]
QED
Definition age_def[simp]:
age k env (v,n) = env (v,n+k:num)
End
Definition eval_io_def:
eval_io env ins =
MAP (λ((x,y),d,e). ((x,y),d, λn. eval (age n env) e)) ins
End
Theorem MAP_FST_eval_io[simp]:
MAP FST (eval_io env ins) = MAP FST ins
Proof
Induct_on ‘ins’ \\ gvs [eval_io_def,FORALL_PROD]
QED
Theorem io_steps_age:
∀k c n s t. io_steps k c n s t ⇔ io_steps k (λl. c (l + n)) 0 s t
Proof
Induct
\\ once_rewrite_tac [io_steps_def] >- simp []
\\ pop_assum $ once_rewrite_tac o single \\ gvs []
QED
Theorem circ_area_age:
circ_area (set area) (set (eval_io (age 1 env) ins))
(set (eval_io (age 1 env) outs)) l =
circ_area (set area) (set (eval_io env ins))
(set (eval_io env outs)) (l + 60)
Proof
gvs [circ_area_def,eval_io_def,MEM_MAP,EXISTS_PROD,PULL_EXISTS]
QED
Theorem circ_output_area_age:
circ_output_area (set (eval_io (age 1 env) outs)) l =
circ_output_area (set (eval_io env outs)) (l + 60)
Proof
gvs [circ_output_area_def,eval_io_def,circ_io_area_def] \\ rw []
\\ gvs [MEM_MAP,EXISTS_PROD,PULL_EXISTS] \\ rw []
\\ gvs [IN_DEF,is_ew_def,is_ns_def]
QED
Theorem age_age:
age n (age k x) = age (n + k) x
Proof
gvs [age_def,FUN_EQ_THM,FORALL_PROD]
QED
Theorem circ_io_lwss_age:
circ_io_lwss (set (eval_io (age 1 env) ins)) l =
circ_io_lwss (set (eval_io env ins)) (l + 60)
Proof
simp [EXTENSION]
\\ gvs [circ_io_lwss_def,eval_io_def] \\ rw []
\\ gvs [MEM_MAP,EXISTS_PROD,PULL_EXISTS,lwss_at_def,age_age]
\\ ‘0 < 60:num’ by gvs []
\\ drule arithmeticTheory.ADD_DIV_ADD_DIV
\\ disch_then $ qspec_then ‘1’ assume_tac \\ gvs []
\\ gvs [IN_DEF,is_ns_def,is_ew_def]
QED
Theorem imp_circuit:
(∀env.
run_to 60
(circ_mod (set area)
(set (eval_io env ins))
(set (eval_io env outs)))
(from_rows (x,y) (MAP (MAP (eval env)) rows))
(from_rows (x,y) (MAP (MAP (eval (age 1 env))) rows)))
⇒
ALL_DISTINCT (MAP FST ins) ∧
ALL_DISTINCT (MAP FST outs) ∧
ALL_DISTINCT area ∧
circ_mod_wf (set area) (set (eval_io env ins)) (set (eval_io env outs))
⇒
circuit
area
(eval_io env ins)
(eval_io env outs)
(from_rows (x,y) (MAP (MAP (eval env)) rows))
Proof
rpt strip_tac
\\ simp [circuit_def,circuit_run_def]
\\ irule run_to_imp_run
\\ qexists_tac ‘60’ \\ simp []
\\ pop_assum kall_tac
\\ qid_spec_tac ‘env’
\\ Induct_on ‘n’
>- gvs [run_to_def,io_steps_def]
\\ rpt strip_tac
\\ gvs [run_to_def,io_steps_def,MULT_CLAUSES]
\\ simp [io_steps_add]
\\ last_x_assum $ qspec_then ‘env’ $ irule_at Any
\\ first_x_assum $ qspec_then ‘age 1 env’ strip_assume_tac
\\ once_rewrite_tac [io_steps_age]
\\ qsuff_tac
‘circ_mod (set area) (set (eval_io (age 1 env) ins))
(set (eval_io (age 1 env) outs)) =
λl. circ_mod (set area) (set (eval_io env ins))
(set (eval_io env outs)) (l + 60)’
>- (rw [] \\ qexists_tac ‘t’ \\ gvs [])
\\ gvs [FUN_EQ_THM,circ_mod_def]
\\ gvs [circ_area_def,circ_io_lwss_age,circ_area_age,circ_output_area_age]
QED
Theorem eval_build_Or[simp]:
eval env (build_Or x y) = eval env (Or x y)
Proof
rw [build_Or_def]
QED
Definition hd_or_false_def:
hd_or_false [] = False ∧
hd_or_false (x::xs) = x
End
Definition gol_row_def:
gol_row x0 (x1::xs)
y0 (y1::ys)
z0 (z1::zs) =
gol_cell y1 (x0, x1, hd_or_false xs,
y0, hd_or_false ys,
z0, z1, hd_or_false zs) ::
gol_row x1 xs
y1 ys
z1 zs ∧
gol_row _ _ _ _ _ _ = []
End
Definition gol_rows_def:
gol_rows prev (row :: rest) =
gol_row False prev
False row
False (case rest of
| [] => REPLICATE (LENGTH row) False
| r :: _ => r)
:: gol_rows row rest ∧
gol_rows prev [] = []
End
Definition gol_step_rows_def:
gol_step_rows [] = [] ∧
gol_step_rows (x::xs) = gol_rows (REPLICATE (LENGTH x) False) (x::xs)
End
Definition check_mask1_def:
(* check_mask1 = LIST_REL (λe m. m ∨ e = False) *)
(check_mask1 [] [] ⇔ T) ∧ (check_mask1 (a::as) [] ⇔ F) ∧
(check_mask1 [] (b::bs) ⇔ F) ∧
(check_mask1 (a::as) (b::bs) ⇔ (b ∨ a = False) ∧ check_mask1 as bs)
End
Definition check_mask_def':
(* check_mask = LIST_REL (LIST_REL (λe m. m ∨ e = False)) *)
(check_mask [] [] ⇔ T) ∧ (check_mask (a::as) [] ⇔ F) ∧
(check_mask [] (b::bs) ⇔ F) ∧
(check_mask (a::as) (b::bs) ⇔ check_mask1 a b ∧ check_mask as bs)
End
Theorem check_mask_def:
∀rows mask.
check_mask rows mask =
LIST_REL (λr m. LIST_REL (λe m. m ∨ e = False) r m) rows mask
Proof
Induct \\ Cases_on ‘mask’ \\ gvs [check_mask_def']
\\ qsuff_tac ‘∀x y. check_mask1 x y = LIST_REL (λe m. m ∨ e = False) x y’ >- gvs []
\\ Induct \\ Cases_on ‘y’ \\ gvs [check_mask1_def]
QED
Definition gol_checked_steps_def:
gol_checked_steps 0 rows mask = SOME rows ∧
gol_checked_steps (SUC n) rows mask =
if check_mask rows mask then
gol_checked_steps n (gol_step_rows rows) mask
else NONE
End
Definition inc_vars_def:
inc_vars rows = MAP (MAP inc) rows
End
Definition or_row_def:
or_row x p [] = [] ∧
or_row x [] row = row ∧
or_row x (p::pat) (r::row) =
if x = 0:num then build_Or p r :: or_row x pat row else
r :: or_row (x-1) (p::pat) row
End
Definition or_at_def:
or_at x y pat [] = [] ∧
or_at x y [] (row::rows) = row::rows ∧
or_at x y (p::pat) (row::rows) =
if y = 0:num then or_row x p row :: or_at x y pat rows else
row :: or_at x (y-1) (p::pat) rows
End
Definition or_lwss_def:
or_lwss rows [] = SOME rows ∧
or_lwss rows (((x,y),d,v)::rest) =
case or_lwss rows rest of
| NONE => NONE
| SOME rows1 =>
SOME (or_at (Num (x * 75 - 5 + 85)) (Num (y * 75 - 5 + 85))
(MAP (MAP (λb. if b then v else False)) (io_gate d)) rows1)
End
Definition diff_row_def:
diff_row [] _ = [] ∧
diff_row xs [] = xs ∧
diff_row (x::xs) (p::pat) = (if p then False else x) :: diff_row xs pat
End
Definition diff_rows_def:
diff_rows [] _ = [] ∧
diff_rows (r::rows) [] = r::rows ∧
diff_rows (r::rows) (p::pats) = diff_row r p :: diff_rows rows pats
End
Definition inter_row_def:
inter_row [] _ = [] ∧
inter_row xs [] = xs ∧
inter_row (x::xs) (p::pat) = (if p then x else False) :: inter_row xs pat
End
Definition inter_rows_def:
inter_rows [] _ = [] ∧
inter_rows (r::rows) [] = r::rows ∧
inter_rows (r::rows) (p::pats) = inter_row r p :: inter_rows rows pats
End
Definition rectangle_def:
rectangle w h rows ⇔
LENGTH rows = 150 * h + 20 ∧
EVERY (λrow. LENGTH row = 150 * w + 20) rows
End
Theorem or_box_row_length:
∀xs x m. LENGTH (or_box_row x m xs) = LENGTH xs
Proof
Induct \\ gvs [or_box_row_def] \\ rw []
QED
Theorem LIST_REL_or_box:
∀xs ys x y m n.
LIST_REL (λx y. LENGTH x = LENGTH y) xs ys ⇒
LIST_REL (λx y. LENGTH x = LENGTH y) (or_box x y m n xs) ys
Proof
Induct \\ gvs [or_box_def,PULL_EXISTS,SF SFY_ss] \\ rw []
\\ gvs [or_box_row_length]
QED
Theorem or_io_areas_rectangle:
or_io_areas xs t = res ∧
rectangle w h t ⇒
rectangle w h res
Proof
rw [] \\ gvs [rectangle_def]
\\ qsuff_tac ‘LIST_REL (λx y. LENGTH x = LENGTH y) (or_io_areas xs t) t’
>- gvs [LIST_REL_EL_EQN,EVERY_MEM,MEM_EL,PULL_EXISTS,SF SFY_ss]
\\ rpt $ pop_assum kall_tac
\\ qid_spec_tac ‘t’
\\ Induct_on ‘xs’ \\ gvs [or_io_areas_def,FORALL_PROD]
>- gvs [LIST_REL_EL_EQN]
\\ rw [] \\ irule LIST_REL_or_box \\ gvs []
QED
Definition simple_checks_def:
simple_checks w h ins outs rows ⇔
rectangle w h rows ∧ h ≠ 0 ∧ w ≠ 0 ∧
ALL_DISTINCT (MAP FST ins ++ MAP FST outs) ∧
let area = make_area w h in
ALL_DISTINCT area ∧
EVERY (λ(p,d,r). MEM (add_pt p (dir_to_xy d)) area ∧
¬MEM (sub_pt p (dir_to_xy d)) area) ins ∧
EVERY (λ(p,d,r). MEM (sub_pt p (dir_to_xy d)) area ∧
¬MEM (add_pt p (dir_to_xy d)) area) outs
End
Definition simulation_ok_def:
simulation_ok w h ins outs rows ⇔
simple_checks w h ins outs rows ∧
let bools = REPLICATE (150 * h + 20) (REPLICATE (150 * w + 20) F) in
let (m1,m2) = masks w h ins outs in
let ins1 = FILTER is_ns ins in
let ins2 = FILTER is_ew ins in
let outs1 = FILTER is_ns outs in
let outs2 = FILTER is_ew outs in
let del1 = or_io_areas outs1 bools in
let del2 = or_io_areas outs2 bools in
let empty = REPLICATE (150 * h + 20) (REPLICATE (150 * w + 20) False) in
case gol_checked_steps 30 rows (shrink m1) of
| NONE => F
| SOME rows1 =>
if or_lwss empty outs1 ≠ SOME (inter_rows rows1 del1) then F else
case or_lwss (diff_rows rows1 del1) ins1 of
| NONE => F
| SOME rowsA =>
case gol_checked_steps 30 rowsA (shrink m2) of
| NONE => F
| SOME rows2 =>
if or_lwss empty outs2 ≠ SOME (inter_rows rows2 del2) then F else
case or_lwss (diff_rows rows2 del2) ins2 of
| NONE => F
| SOME rowsB =>
inc_vars rows = rowsB
End
Theorem opt_bool =
“option_CASE x F h = T” |> SCONV [AllCaseEqs()] |> SRULE [];
Definition steps_def:
steps s1 t s2 ⇔
s2 = FUNPOW step 30 s1 ∧
∀n. n < 30 ⇒ infl (FUNPOW step n s1) ⊆ t
End
Theorem io_steps_FUNPOW:
∀k n s cc.
(∀i. i < k ⇒
infl (FUNPOW step i s) ⊆ (cc (i + n)).area ∧
(cc (i + n)).assert_area = {} ∧
(cc (i + n)).assert_content = {} ∧
(cc (i + n)).deletions = {} ∧
(cc (i + n)).insertions = {}) ⇒
io_steps k cc n s (FUNPOW step k s)
Proof
Induct \\ gvs [io_steps_def] \\ rw [] \\ gvs [FUNPOW]
\\ last_x_assum $ irule_at Any \\ conj_tac
>- (gen_tac \\ strip_tac
\\ last_x_assum $ qspec_then ‘SUC i’ mp_tac \\ gvs [FUNPOW,ADD1])
\\ gvs [io_step_def]
\\ pop_assum $ qspec_then ‘0’ assume_tac \\ gvs []
QED
Theorem circ_io_lwss_empty:
i < 29 ⇒ circ_io_lwss ins i = ∅ ∧ circ_io_lwss ins (i + 30) = ∅
Proof
simp [EXTENSION]
\\ gvs [circ_io_lwss_def]
\\ gvs [FORALL_PROD]
\\ gvs [lwss_at_def]
\\ CCONTR_TAC \\ gvs []
QED
Triviality run_to_60_lemma:
(∃s1 s2 s3.
steps s (circ_area area ins outs 0) s1 ∧
s1 ∩ circ_output_area outs 29 = circ_io_lwss outs 29 ∧
s2 = circ_io_lwss ins 29 ∪ (s1 DIFF circ_output_area outs 29) ∧
steps s2 (circ_area area ins outs 30) s3 ∧
s3 ∩ circ_output_area outs 59 = circ_io_lwss outs 59 ∧
t = circ_io_lwss ins 59 ∪ (s3 DIFF circ_output_area outs 59))
⇒
run_to 60 (circ_mod area ins outs) s t
Proof
strip_tac
\\ gvs [run_to_def]
\\ rewrite_tac [EVAL “30 + 30:num” |> GSYM]
\\ rewrite_tac [io_steps_add] \\ gvs []
\\ qexists_tac ‘circ_io_lwss ins 29 ∪ (s1 DIFF circ_output_area outs 29)’
\\ conj_tac
>-
(ntac 2 (pop_assum kall_tac) \\ gvs [steps_def]
\\ simp [io_steps_def]
\\ rewrite_tac [EVAL “1 + 29:num” |> GSYM]
\\ rewrite_tac [io_steps_add] \\ gvs []
\\ qexists_tac ‘FUNPOW step 29 s’
\\ conj_tac
>- (irule io_steps_FUNPOW \\ gvs [circ_mod_def,circ_area_def]
\\ gvs [circ_output_area_def,circ_io_lwss_empty,circ_io_area_def])
\\ ntac 2 $ simp [Once (oneline io_steps_def)]
\\ gvs [io_step_def,circ_mod_def,SF SFY_ss]
\\ ‘step (FUNPOW step 29 s) = FUNPOW step 30 s’
by rewrite_tac [EVAL “SUC 29” |> GSYM, FUNPOW_SUC]
\\ gvs [] \\ gvs [circ_area_def])
\\ last_x_assum kall_tac
\\ last_x_assum kall_tac
\\ qabbrev_tac ‘t5 = circ_io_lwss ins 29 ∪ (s1 DIFF circ_output_area outs 29)’
\\ pop_assum kall_tac
\\ rewrite_tac [EVAL “1 + 29:num” |> GSYM]
\\ rewrite_tac [io_steps_add] \\ gvs []
\\ qexists_tac ‘FUNPOW step 29 t5’
\\ gvs [steps_def]
\\ conj_tac
>- (irule io_steps_FUNPOW \\ gvs [circ_mod_def,circ_area_def]
\\ gvs [circ_output_area_def,circ_io_lwss_empty,circ_io_area_def])
\\ ntac 2 $ simp [Once (oneline io_steps_def)]
\\ gvs [io_step_def,circ_mod_def,SF SFY_ss]
\\ ‘step (FUNPOW step 29 t5) = FUNPOW step 30 t5’
by rewrite_tac [EVAL “SUC 29” |> GSYM, FUNPOW_SUC]
\\ gvs [] \\ gvs [circ_area_def]
QED
Theorem length_gol_row:
∀xs ys zs x1 y1 z1.
LENGTH xs = LENGTH ys ∧ LENGTH zs = LENGTH ys ⇒
LENGTH (gol_row x1 xs y1 ys z1 zs) = LENGTH ys
Proof
Induct \\ gvs [gol_row_def]
\\ Cases_on ‘ys’ \\ gvs []
\\ Cases_on ‘zs’ \\ gvs []
\\ gvs [SF SFY_ss,gol_row_def]
QED
Theorem gol_rows_length:
∀rows prev.
EVERY (λrow. LENGTH row = LENGTH prev) rows ⇒
LIST_REL (λx y. LENGTH x = LENGTH y) rows (gol_rows prev rows)
Proof
Induct \\ gvs [gol_rows_def] \\ rw []
\\ DEP_REWRITE_TAC [length_gol_row] \\ gvs []
\\ Cases_on ‘rows’ \\ gvs []
\\ Cases_on ‘h’ \\ gvs []
\\ Cases_on ‘prev’ \\ gvs []
\\ DEP_REWRITE_TAC [length_gol_row] \\ gvs []
\\ Cases_on ‘h'’ \\ gvs []
\\ DEP_REWRITE_TAC [length_gol_row] \\ gvs []
QED
Theorem gol_step_rows_length:
∀rows k.
EVERY (λrow. LENGTH row = k) rows ⇒
LIST_REL (λx y. LENGTH x = LENGTH y) rows (gol_step_rows rows)
Proof
gen_tac \\ Cases_on ‘rows = []’ \\ gvs [gol_step_rows_def]
\\ ‘gol_step_rows rows = gol_rows (REPLICATE (LENGTH (HD rows)) False) rows’ by
(Cases_on ‘rows’ \\ gvs [gol_step_rows_def])
\\ gvs [] \\ rw []
\\ irule gol_rows_length \\ gvs []
\\ Cases_on ‘rows’ \\ gvs []
QED
Theorem gol_step_rows_rectangle:
rectangle w h rows ⇒
rectangle w h (gol_step_rows rows)
Proof
rw [rectangle_def]
\\ qspec_then ‘rows’ drule gol_step_rows_length
\\ gvs [LIST_REL_EL_EQN,MEM_EL,PULL_EXISTS,EVERY_MEM]
QED
Theorem gol_checked_steps_rectangle:
∀n rows m1 rows1.
gol_checked_steps n rows m1 = SOME rows1 ∧
rectangle w h rows ⇒
rectangle w h rows1
Proof
Induct \\ gvs [gol_checked_steps_def] \\ rw []
\\ last_x_assum $ drule_then irule
\\ irule gol_step_rows_rectangle \\ gvs []
QED
Theorem oEL_MAP_EQ_SOME:
∀xs f n y.
LLOOKUP (MAP f xs) n = SOME y ⇔
∃x. LLOOKUP xs n = SOME x ∧ y = f x
Proof
Induct \\ gvs [oEL_def] \\ rw [] \\ eq_tac \\ rw []
QED
Theorem LLOOKUP_gol_row:
∀xs ys zs x y z n res.
LLOOKUP (gol_row x xs y ys z zs) n = SOME res ⇔
n < LENGTH xs ∧ n < LENGTH ys ∧ n < LENGTH zs ∧
res = gol_cell (EL n ys)
((if n = 0 then x else EL (n-1) xs),
EL n xs,
(if n+1 < LENGTH xs then EL (n+1) xs else False),
(if n = 0 then y else EL (n-1) ys),
(if n+1 < LENGTH ys then EL (n+1) ys else False),
(if n = 0 then z else EL (n-1) zs),
EL n zs,
(if n+1 < LENGTH zs then EL (n+1) zs else False))
Proof
Induct \\ Cases_on ‘ys’ \\ Cases_on ‘zs’ \\ gvs [gol_row_def,oEL_def]
\\ rpt gen_tac \\ Cases_on ‘n’ \\ gvs []
\\ ‘∀xs. (if 1 < SUC (LENGTH xs) then HD xs else False) = hd_or_false xs’
by (Cases \\ gvs [hd_or_false_def]) \\ gvs []
>- (eq_tac \\ rw [])
\\ gvs [ADD_CLAUSES]
\\ Cases_on ‘n' ’ \\ gvs []
QED
Theorem LLOOKUP_gol_rows:
∀xs prev n ys.
LLOOKUP (gol_rows prev xs) n = SOME ys ⇔
n < LENGTH xs ∧
ys = gol_row False (if n = 0 then prev else EL (n-1) xs)
False (EL n xs)
False (if n+1 < LENGTH xs then EL (n+1) xs
else REPLICATE (LENGTH (EL n xs)) False)
Proof
Induct \\ gvs [gol_rows_def,oEL_def] \\ rpt gen_tac
\\ IF_CASES_TAC
>- (gvs [] \\ Cases_on ‘xs’ \\ gvs []
\\ rw [] \\ eq_tac \\ rw [])
\\ gvs [GSYM ADD1]
\\ Cases_on ‘n’ \\ gvs [] \\ gvs [ADD1]
\\ Cases_on ‘xs’ \\ gvs []
\\ Cases_on ‘n'’ \\ gvs []
QED
Definition decide_step_def:
decide_step y2 (x1,x2,x3,y1,y3,z1,z2,z3) =
if y2 then
b2n x1 + b2n x2 + b2n x3 +
b2n y1 + b2n y3 +
b2n z1 + b2n z2 + b2n z3 ∈ {2;3}
else
b2n x1 + b2n x2 + b2n x3 +
b2n y1 + b2n y3 +
b2n z1 + b2n z2 + b2n z3 = 3
End
Theorem IN_step_lemma:
(x,y) ∈ step s ⇔
decide_step ((x,y) ∈ s)
((x-1,y-1) ∈ s, (x,y-1) ∈ s, (x+1,y-1) ∈ s,
(x-1,y) ∈ s, (x+1,y ) ∈ s,
(x-1,y+1) ∈ s, (x,y+1) ∈ s, (x+1,y+1) ∈ s)
Proof
gvs [IN_step,live_adj_eq,decide_step_def] \\ gvs [IN_DEF]
QED
Theorem y_SUB_IN_from_rows:
(x,y-1) ∈ from_rows (a,b) rows ⇔ (x,y) ∈ from_rows (a,b) ([]::rows)
Proof
gvs [IN_from_rows,oEL_def]
\\ rw [] \\ eq_tac \\ rw []
\\ gvs [SF intLib.INT_ARITH_ss]
>- (qexists_tac ‘dy+1’ \\ gvs [SF intLib.INT_ARITH_ss])
\\ Cases_on ‘dy’ \\ gvs [] \\ gvs [oEL_def]
\\ first_x_assum $ irule_at $ Pos last
\\ first_x_assum $ irule_at $ Pos last
\\ gvs [SF intLib.INT_ARITH_ss]
QED
Theorem x_SUB_IN_from_rows:
(x-1,y) ∈ from_rows (a,b) rows ⇔ (x,y) ∈ from_rows (a,b) (MAP (λr. F::r) rows)
Proof
gvs [IN_from_rows,oEL_def,oEL_MAP_EQ_SOME,PULL_EXISTS,CaseEq"bool"]
\\ rw [] \\ eq_tac \\ rw []
\\ gvs [SF intLib.INT_ARITH_ss]
>- (qexists_tac ‘dx+1’ \\ gvs [SF intLib.INT_ARITH_ss])
\\ first_x_assum $ irule_at $ Pos last
\\ gvs [SF intLib.INT_ARITH_ss]
\\ intLib.COOPER_TAC
QED
Theorem LENGTH_if:
LENGTH (if b then xs else ys) =
if b then LENGTH xs else LENGTH ys
Proof
rw []
QED
Theorem count_falses_lemma:
∀xs.
SUM (MAP (b2n o (λe. e = False)) xs) +
SUM (MAP (b2n o eval env) xs) ≤ LENGTH xs
Proof
Induct \\ gvs [] \\ rw []
\\ Cases_on ‘h = False’ \\ gvs []
\\ rw [oneline b2n_def]
QED
Definition vars_of_def:
vars_of (And e1 e2) = vars_of e1 ∪ vars_of e2 ∧
vars_of (Or e1 e2) = vars_of e1 ∪ vars_of e2 ∧
vars_of (Not e1) = vars_of e1 ∧
vars_of (Var g n) = {(g,n)} ∧
vars_of _ = {}
End
Theorem eval_build_Not:
eval env (build_Not e) = eval env (Not e)
Proof
Cases_on ‘e’ \\ gvs [build_Not_def]
QED
Theorem eval_build_If:
eval env (build_If x y z) =
if eval env x then eval env y else eval env z
Proof
rw [build_If_def,eval_build_Not]
QED
Theorem eval_bexp_eq_eval:
EVERY (λ(v,x). env v ⇔ x) l ∧
vars_of x ⊆ set (MAP FST l) ⇒
eval_bexp l x = eval env x
Proof
Induct_on ‘x’ \\ gvs [vars_of_def,eval_bexp_def]
\\ Induct_on ‘l’ \\ gvs [] \\ PairCases \\ gvs []
\\ rw [] \\ gvs []
QED
Theorem eval_to_bexp:
eval env (to_bexp b) = b
Proof
Cases_on ‘b’ \\ gvs []
QED
Theorem eval_gol_eval:
∀vars l env x1 x2 x3 y1 y2 y3 z1 z2 z3.
vars_of x1 ∪ vars_of x2 ∪ vars_of x3 ∪
vars_of y1 ∪ vars_of y2 ∪ vars_of y3 ∪
vars_of z1 ∪ vars_of z2 ∪ vars_of z3 ⊆ set vars ∪ set (MAP FST l) ∧
EVERY (λ(v,x). env v = x) l ⇒
eval env (gol_eval vars l y2 (x1,x2,x3,y1,y3,z1,z2,z3)) =
decide_step (eval env y2)
(eval env x1,eval env x2,eval env x3,eval env y1,
eval env y3,eval env z1,eval env z2,eval env z3)
Proof
reverse Induct
>-
(PairCases
\\ simp [Once gol_eval_def] \\ rw [] \\ rw [eval_build_If]
\\ last_x_assum irule
\\ gvs [SUBSET_DEF, SF DNF_ss, AC DISJ_COMM DISJ_ASSOC])
\\ simp [Once gol_eval_def]
\\ gvs [decide_step_def,eval_bexp8_def]
\\ rpt strip_tac
\\ drule eval_bexp_eq_eval \\ gvs [eval_to_bexp]
QED
Theorem get_bvars_thm:
∀x acc. set (get_bvars x acc) = vars_of x ∪ set acc
Proof
Induct \\ gvs [get_bvars_def,vars_of_def, AC UNION_COMM UNION_ASSOC]
\\ Induct_on ‘acc’ \\ gvs [add_to_sorted_def] \\ rw []
\\ gvs [EXTENSION] \\ rw [] \\ eq_tac \\ rw []
\\ rpt (PairCases_on ‘h’ \\ gvs [])
\\ PairCases_on ‘x’ \\ gvs []
QED
Theorem gol_cell_decide_step:
px1 = eval env x1 ∧
px2 = eval env x2 ∧
px3 = eval env x3 ∧
py1 = eval env y1 ∧
py2 = eval env y2 ∧
py3 = eval env y3 ∧
pz1 = eval env z1 ∧
pz2 = eval env z2 ∧
pz3 = eval env z3
⇒
eval env (gol_cell y2 (x1,x2,x3,y1,y3,z1,z2,z3)) =
decide_step py2 (px1,px2,px3,py1,py3,pz1,pz2,pz3)
Proof
rw [] \\ rw [gol_cell_def]
>-
(gvs [decide_step_def] \\ gvs [count_falses_def]
\\ qspec_then ‘[x1;x2;x3;y1;y2;y3;z1;z2;z3]’ assume_tac count_falses_lemma
\\ gvs [] \\ rw [] \\ CCONTR_TAC \\ gvs [])
\\ irule eval_gol_eval \\ gvs []
\\ gvs [get_bvars8_def,get_bvars_thm,SUBSET_DEF]
QED
Theorem gol_step_rows:
EVERY (λr. HD r = False ∧ LAST r = False) rows ∧
(rows ≠ [] ⇒ EVERY (λx. x = False) (HD rows)) ∧
(rows ≠ [] ⇒ EVERY (λx. x = False) (LAST rows)) ∧
rectangle w h rows ⇒
from_rows (-85,-85) (MAP (MAP (eval env)) (gol_step_rows rows)) =
step (from_rows (-85,-85) (MAP (MAP (eval env)) rows))
Proof
Cases_on ‘rows’ >- gvs [rectangle_def]
\\ rewrite_tac [gol_step_rows_def,NOT_CONS_NIL]
\\ rename [‘x::xs’]
\\ ‘LENGTH x = LENGTH (HD (x::xs))’ by gvs []
\\ asm_rewrite_tac []
\\ qspec_tac (‘x::xs’,‘ys’)
\\ pop_assum kall_tac \\ rw []
\\ gvs [EXTENSION] \\ PairCases
\\ rename [‘(x,y) ∈ _’]
\\ simp [IN_step_lemma]
\\ rewrite_tac [x_SUB_IN_from_rows]
\\ rewrite_tac [y_SUB_IN_from_rows]
\\ simp [IN_from_rows,oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ gvs [LLOOKUP_gol_rows]
\\ gvs [LLOOKUP_gol_row,PULL_EXISTS]
\\ Cases_on ‘x < -85’ >-
(‘∀dx. x ≠ -85 + &dx’ by intLib.COOPER_TAC \\ gvs []
\\ ‘∀dx. x + 1 = -85 + &dx <=>
x + 1 = -85 + &dx ∧ dx = 0’ by intLib.COOPER_TAC
\\ pop_assum (fn th => once_rewrite_tac [th])
\\ gvs [] \\ gvs [oEL_THM] \\ gvs [EVERY_EL, SF CONJ_ss]
\\ EVAL_TAC \\ rw [oneline b2n_def])
\\ Cases_on ‘y < -85’ >-
(‘∀dx. y ≠ -85 + &dx’ by intLib.COOPER_TAC \\ gvs []
\\ ‘∀dx. y + 1 = -85 + &dx <=>
y + 1 = -85 + &dx ∧ dx = 0’ by intLib.COOPER_TAC
\\ pop_assum (fn th => once_rewrite_tac [th])
\\ gvs [] \\ gvs [oEL_THM] \\ gvs [EVERY_EL, SF CONJ_ss]
\\ EVAL_TAC \\ rw [oneline b2n_def])
\\ ‘∃dx. x = -85 + &dx’ by intLib.COOPER_TAC \\ gvs []
\\ ‘∃dy. y = -85 + &dy’ by intLib.COOPER_TAC \\ gvs []
\\ gvs [GSYM integerTheory.INT_ADD_ASSOC,integerTheory.INT_ADD]
\\ reverse $ Cases_on ‘dy < LENGTH ys’ \\ gvs []
>-
(gvs [oEL_THM]
\\ reverse $ Cases_on ‘dy < SUC (LENGTH ys)’ \\ gvs [] >- EVAL_TAC
\\ ‘dy = LENGTH ys’ by gvs [] \\ gvs []
\\ DEP_REWRITE_TAC [EL_CONS]
\\ gvs [MAP_MAP_o,arithmeticTheory.PRE_SUB1]
\\ conj_tac >- gvs [rectangle_def]
\\ gvs [EVERY_EL]
\\ gvs [SF CONJ_ss, GSYM (SRULE [PRE_SUB1] LAST_EL), EL_MAP]
\\ ‘dx < LENGTH (EL (LENGTH ys − 1) (MAP (MAP (eval env)) ys)) ∧
EL dx (EL (LENGTH ys − 1) (MAP (MAP (eval env)) ys)) ⇔ F’ by
(DEP_ONCE_REWRITE_TAC [EL_MAP]
\\ gvs [SF CONJ_ss, EL_MAP]
\\ DEP_REWRITE_TAC [GSYM (SRULE [PRE_SUB1] LAST_EL)]
\\ gvs [rectangle_def]
\\ ‘LENGTH ys ≠ 0’ by decide_tac
\\ gvs []
\\ CCONTR_TAC \\ gvs []
\\ gvs [SF CONJ_ss, EL_MAP])
\\ asm_rewrite_tac []
\\ EVAL_TAC \\ rw [oneline b2n_def])
\\ gvs [LENGTH_if]
\\ ‘∀n. n < LENGTH ys ⇒ LENGTH (EL n ys) = LENGTH (HD ys)’ by
(gvs [rectangle_def,EVERY_EL]
\\ Cases_on ‘ys’ \\ gvs []
\\ first_x_assum $ qspec_then ‘0’ mp_tac \\ gvs [])
\\ gvs [SF CONJ_ss]
\\ reverse $ Cases_on ‘dx < LENGTH (HD ys)’ \\ gvs []
>-
(gvs [oEL_THM, SF CONJ_ss]
\\ Cases_on ‘dy’ \\ gvs []
>- (EVAL_TAC \\ rw [oneline b2n_def])
\\ gvs [EL_MAP]
\\ reverse $ Cases_on ‘dx < SUC (LENGTH (HD ys))’ \\ gvs []
>- EVAL_TAC
\\ DEP_REWRITE_TAC [EL_CONS] \\ gvs []
\\ conj_asm1_tac >- (Cases_on ‘ys’ \\ gvs [rectangle_def])
\\ gvs [EL_MAP]
\\ ‘eval env (EL (PRE dx) (EL n ys)) = F’ by
(‘dx = LENGTH (HD ys)’ by gvs []
\\ gvs [PRE_SUB1]
\\ ‘LENGTH (HD ys) = LENGTH (EL n ys)’ by simp []
\\ asm_rewrite_tac []
\\ DEP_REWRITE_TAC [GSYM (SRULE [PRE_SUB1] LAST_EL)]
\\ pop_assum kall_tac
\\ gvs [EVERY_EL]
\\ rewrite_tac [GSYM LENGTH_NIL]
\\ ‘n < LENGTH ys’ by gvs []
\\ res_tac
\\ decide_tac)
\\ EVAL_TAC \\ rw [oneline b2n_def])
\\ irule gol_cell_decide_step
\\ rpt strip_tac
>- (Cases_on ‘dy’ \\ gvs [oEL_def,EL_REPLICATE]
\\ gvs [oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ Cases_on ‘dx’ \\ gvs [oEL_def]
\\ gvs [oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ gvs [oEL_THM])
>- (Cases_on ‘dy’ \\ gvs [oEL_def,EL_REPLICATE]
\\ gvs [oEL_MAP_EQ_SOME,PULL_EXISTS] \\ gvs [oEL_THM])
>- (Cases_on ‘dy’ \\ gvs [oEL_def,EL_REPLICATE]
\\ gvs [oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ gvs [oEL_THM] \\ rw [])
>- (Cases_on ‘dx’ \\ gvs [oEL_def,oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ gvs [oEL_THM])
>- (Cases_on ‘dx’ \\ gvs [oEL_def,oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ gvs [oEL_THM])
>- (rw [] \\ gvs [oEL_THM])
>- (Cases_on ‘dx’ \\ gvs [oEL_def,oEL_MAP_EQ_SOME,PULL_EXISTS]
\\ rw [] \\ gvs [oEL_THM,EL_MAP,EL_REPLICATE])
\\ rw [] \\ gvs [oEL_THM,EL_MAP,EL_REPLICATE]
QED
Theorem check_mask_thm:
check_mask rows m ⇒
from_rows (-85,-85) (MAP (MAP (eval env)) rows) ⊆
from_rows (-85,-85) m
Proof
gvs [check_mask_def,LIST_REL_EL_EQN,SUBSET_DEF,FORALL_PROD]
\\ rw [IN_from_rows] \\ gvs [oEL_THM,EL_MAP]
\\ first_x_assum drule \\ strip_tac
\\ pop_assum $ qspec_then ‘dx’ mp_tac \\ gvs []
\\ strip_tac \\ gvs []
QED
Theorem check_mask_F:
check_mask rows m ⇒
∀x y row.
oEL y m = SOME row ∧ oEL x row = SOME F ⇒
∃r. oEL y rows = SOME r ∧ oEL x r = SOME False
Proof
gvs [check_mask_def,LIST_REL_EL_EQN,oEL_THM] \\ metis_tac []
QED
Theorem HD_EL:
HD xs = EL 0 xs
Proof
Cases_on ‘xs’ \\ gvs []
QED
Theorem from_row_append:
∀xs ys x y.
from_row (x,y) (xs ++ ys) =
from_row (x,y) xs ∪ from_row (x + & LENGTH xs,y) ys
Proof
Induct \\ gvs [from_row_def]
\\ Cases \\ gvs [from_row_def,ADD1]
\\ rpt gen_tac
\\ gvs [UNION_ASSOC]
\\ rpt AP_TERM_TAC
\\ rpt AP_THM_TAC
\\ rpt AP_TERM_TAC
\\ gvs [] \\ intLib.COOPER_TAC
QED
Theorem from_rows_append:
∀xs ys x y.
from_rows (x,y) (xs ++ ys) =
from_rows (x,y) xs ∪ from_rows (x,y + & LENGTH xs) ys
Proof
Induct \\ gvs [from_rows_def]
\\ rpt gen_tac
\\ gvs [UNION_ASSOC]
\\ rpt AP_TERM_TAC
\\ rpt AP_THM_TAC
\\ rpt AP_TERM_TAC
\\ gvs [] \\ intLib.COOPER_TAC
QED
Triviality from_row_rep_F:
∀x y. from_row (x,y) (REPLICATE l F) = {}
Proof
Induct_on ‘l’ \\ gvs [from_row_def]
QED
Triviality from_rows_rep_rep_F:
from_rows (x,y) (REPLICATE k (REPLICATE l F)) = {}
Proof
irule from_rows_EMPTY \\ gvs []
QED
Theorem from_rows_add_margin:
from_rows (x,y) (add_margin F k m) =
from_rows (x + &k,y + &k) m
Proof
gvs [add_margin_def,from_rows_append]
\\ gvs [from_rows_rep_rep_F]
\\ qid_spec_tac ‘y’
\\ qid_spec_tac ‘x’
\\ Induct_on ‘m’ \\ gvs [from_rows_def]
\\ gvs [from_row_append,from_row_rep_F]
\\ rpt gen_tac \\ AP_TERM_TAC
\\ first_x_assum $ qspecl_then [‘x’,‘y+1’] mp_tac
\\ gvs [AC integerTheory.INT_ADD_COMM integerTheory.INT_ADD_ASSOC]
QED
Triviality from_row_cons_imp:
(p,q) ∈ from_row (x,y) (t::ts) ⇒
(p,q) = (x,y) ∧ t ∨ (p,q) ∈ from_row (x+1,y) ts
Proof
Cases_on ‘t’ \\ gvs [from_row_def]
QED
Theorem from_row_cons_eq:
(a,b) ∈ from_row (x,y) (r::rs) ⇔
(r ∧ a = x ∧ b = y) ∨ (a,b) ∈ from_row (x+1,y) rs
Proof
Cases_on ‘r’ \\ gvs [from_row_def]
QED
Theorem from_row_shrink_row:
∀r1 r2 r3 a b x y.
(a,b) ∈ from_row (x,y) (shrink_row r1 r2 r3) ⇒
(a-1,b-1) ∈ from_row (x-1,y-1) r1 ∧
(a,b-1) ∈ from_row (x-1,y-1) r1 ∧
(a+1,b-1) ∈ from_row (x-1,y-1) r1 ∧
(a-1,b) ∈ from_row (x-1,y) r2 ∧
(a,b) ∈ from_row (x-1,y) r2 ∧
(a+1,b) ∈ from_row (x-1,y) r2 ∧
(a-1,b+1) ∈ from_row (x-1,y+1) r3 ∧
(a,b+1) ∈ from_row (x-1,y+1) r3 ∧
(a+1,b+1) ∈ from_row (x-1,y+1) r3
Proof
ho_match_mp_tac shrink_row_ind
\\ gvs [shrink_row_def,from_row_def]
\\ rpt gen_tac \\ disch_tac
\\ rpt gen_tac \\ disch_tac
\\ dxrule from_row_cons_imp
\\ strip_tac \\ gvs []
>- gvs [from_row_def]
\\ once_rewrite_tac [from_row_cons_eq]
\\ metis_tac [intLib.COOPER_PROVE “m + n - n:int = m”,
intLib.COOPER_PROVE “m - n + n:int = m”]
QED
Theorem from_rows_shrink:
from_rows (x,y) (shrink m) ⊆
COMPL (infl (COMPL (from_rows (x,y) m)))
Proof
gvs [shrink_def,from_rows_add_margin]
\\ qsuff_tac
‘∀m x y.
from_rows (x,y) (shrink_all m) ⊆
COMPL (infl (COMPL (from_rows (x-1,y-1) m)))’
>- metis_tac [intLib.COOPER_PROVE “x+1-1:int = x”]
\\ rewrite_tac [SUBSET_DEF]
\\ once_rewrite_tac [GSYM PAIR]
\\ rewrite_tac [IN_COMPL_infl_COMPL]
\\ gvs [FORALL_PROD]
\\ ho_match_mp_tac shrink_all_ind
\\ gvs [shrink_all_def,from_rows_def]
\\ rpt gen_tac \\ disch_tac
\\ rpt gen_tac \\ reverse strip_tac
>- metis_tac [intLib.COOPER_PROVE “m + n - n:int = m”,
intLib.COOPER_PROVE “m - n + n:int = m”]
\\ dxrule from_row_shrink_row \\ gvs []
QED
Theorem length_shrink_row:
∀xs ys zs.
LENGTH xs = LENGTH ys ∧
LENGTH zs = LENGTH ys ⇒
LENGTH (shrink_row xs ys zs) = LENGTH ys - 2
Proof
ho_match_mp_tac shrink_row_ind \\ gvs [shrink_row_def]
QED
Theorem length_shrink_all:
∀m. LENGTH (shrink_all m) = LENGTH m - 2
Proof
ho_match_mp_tac shrink_all_ind \\ gvs [shrink_all_def]
QED
Theorem shrink_rectangle:
rectangle w h m ⇒ rectangle w h (shrink m)
Proof
rw [rectangle_def,EVERY_MEM,shrink_def,add_margin_def]
\\ gvs [length_shrink_all,MEM_MAP]
>-
(CASE_TAC \\ gvs []
\\ Cases_on ‘m’ \\ gvs []
\\ rename [‘shrink_all (x::xs)’] \\ Cases_on ‘xs’ \\ gvs []
\\ rename [‘shrink_all (x::y::xs)’] \\ Cases_on ‘xs’ \\ gvs []
\\ gvs [shrink_all_def] \\ gvs [SF DNF_ss]
\\ DEP_REWRITE_TAC [length_shrink_row] \\ gvs [])
>-
(last_x_assum kall_tac
\\ gvs [GSYM EVERY_MEM]
\\ rpt $ pop_assum mp_tac
\\ qid_spec_tac ‘m’
\\ ho_match_mp_tac shrink_all_ind \\ gvs [shrink_all_def]
\\ rw [] \\ gvs [SF SFY_ss]
\\ DEP_REWRITE_TAC [length_shrink_row] \\ gvs [])
>-
(CASE_TAC \\ gvs []
\\ Cases_on ‘m’ \\ gvs []
\\ rename [‘shrink_all (x::xs)’] \\ Cases_on ‘xs’ \\ gvs []
\\ rename [‘shrink_all (x::y::xs)’] \\ Cases_on ‘xs’ \\ gvs []
\\ gvs [shrink_all_def] \\ gvs [SF DNF_ss]
\\ DEP_REWRITE_TAC [length_shrink_row] \\ gvs [])
QED
Theorem gol_checked_steps_gen:
∀rows rows1 area.
gol_checked_steps 30 rows (shrink m) = SOME rows1 ∧
rectangle w h rows ∧
rectangle w h m ∧
area = from_rows (-85,-85) m ⇒
steps (from_rows (-85,-85) (MAP (MAP (eval env)) rows))
area
(from_rows (-85,-85) (MAP (MAP (eval env)) rows1))
Proof
simp [steps_def]
\\ qspec_tac (‘30:num’,‘k’)
\\ Induct
\\ gvs [gol_checked_steps_def]
\\ rpt gen_tac \\ strip_tac
\\ last_x_assum drule
\\ impl_tac >- gvs [gol_step_rows_rectangle]
\\ strip_tac \\ gvs []
\\ qabbrev_tac ‘m1 = shrink m’