-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathsource_to_flatProofScript.sml
5849 lines (5566 loc) · 185 KB
/
source_to_flatProofScript.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
(*
Correctness proof for source_to_flat
*)
open preamble semanticsTheory namespacePropsTheory
semanticPrimitivesTheory semanticPrimitivesPropsTheory
source_to_flatTheory flatLangTheory flatSemTheory flatPropsTheory
backendPropsTheory experimentalLib source_evalProofTheory
local open flat_elimProofTheory flat_patternProofTheory in end
val _ = new_theory "source_to_flatProof";
val _ = temp_delsimps ["NORMEQ_CONV"]
val _ = diminish_srw_ss ["ABBREV"]
val _ = temp_delsimps ["lift_disj_eq", "lift_imp_disj", "getOpClass_def"]
val _ = set_trace "BasicProvers.var_eq_old" 1
val grammar_ancestry =
["source_to_flat","flatProps","namespaceProps",
"semantics","semanticPrimitivesProps","ffi","lprefix_lub",
"backend_common","misc","backendProps", "source_evalProof"];
val _ = set_grammar_ancestry grammar_ancestry;
Triviality compile_exps_length:
LENGTH (compile_exps t m es) = LENGTH es
Proof
induct_on `es` >>
rw [compile_exp_def]
QED
Theorem mapi_map:
!f g l. MAPi f (MAP g l) = MAPi (\i x. f i (g x)) l
Proof
Induct_on `l` >>
rw [combinTheory.o_DEF]
QED
Triviality fst_lem:
(λ(p1,p1',p2). p1) = FST
Proof
rw [FUN_EQ_THM] >>
pairarg_tac >>
rw []
QED
Triviality funion_submap:
FUNION x y SUBMAP z ∧ DISJOINT (FDOM x) (FDOM y) ⇒ y SUBMAP z
Proof
rw [SUBMAP_DEF, DISJOINT_DEF, EXTENSION, FUNION_DEF] >>
metis_tac []
QED
Triviality flookup_funion_submap:
(x ⊌ y) SUBMAP z ∧
FLOOKUP (x ⊌ y) k = SOME v
⇒
FLOOKUP z k = SOME v
Proof
rw [SUBMAP_DEF, FLOOKUP_DEF] >>
metis_tac []
QED
Theorem FILTER_MAPi_ID:
∀ls f. FILTER P (MAPi f ls) = MAPi f ls ⇔
(∀n. n < LENGTH ls ⇒ P (f n (EL n ls)))
Proof
Induct \\ reverse(rw[])
>- (
qmatch_goalsub_abbrev_tac`a ⇔ b`
\\ `¬a`
by (
simp[Abbr`a`]
\\ disch_then(mp_tac o Q.AP_TERM`LENGTH`)
\\ rw[]
\\ specl_args_of_then``FILTER``LENGTH_FILTER_LEQ mp_tac
\\ simp[] )
\\ simp[Abbr`b`]
\\ qexists_tac`0`
\\ simp[] )
\\ simp[Once FORALL_NUM, SimpRHS]
QED
(* -- *)
(* value relation *)
(* bind locals with an arbitrary trace *)
Definition bind_locals_def:
bind_locals ts locals comp_map =
nsBindList (MAP2 (\t x. (x, Local t x)) ts locals) comp_map
End
Triviality nsAppend_bind_locals:
∀funs.
nsAppend (alist_to_ns (MAP (λx. (x,Local t x)) (MAP FST funs))) (bind_locals ts locals comp_map) =
bind_locals (REPLICATE (LENGTH funs) t ++ ts) (MAP FST funs ++ locals) comp_map
Proof
Induct_on`funs`>>fs[FORALL_PROD,bind_locals_def,namespaceTheory.nsBindList_def]
QED
Triviality nsBindList_pat_tups_bind_locals:
∀ls.
∃tss.
nsBindList (pat_tups t ls) (bind_locals ts locals comp_map) =
bind_locals (tss ++ ts) (ls ++ locals) comp_map ∧
LENGTH tss = LENGTH ls
Proof
Induct>>rw[pat_tups_def,namespaceTheory.nsBindList_def,bind_locals_def]>>
qexists_tac`(t § (LENGTH ls + 1))::tss`>>simp[]
QED
Datatype:
global_env =
<| v : flatSem$v option list; c : (ctor_id # type_id) # num |-> stamp;
tys : num |-> (ctor_id # num) list |>
End
Theorem submap_distinct_fupdate_flookup:
x ∉ FDOM f ==>
(f |+ (x,y) ⊑ g <=> FLOOKUP g x = SOME y /\ f ⊑ g)
Proof
rw [SUBMAP_FUPDATE, FLOOKUP_DEF]
\\ EQ_TAC \\ rw []
\\ fs [SUBMAP_DEF]
\\ fs [DOMSUB_FAPPLY_THM]
\\ metis_tac []
QED
Theorem submap_fupdate_flookup:
(f |+ (x,y) ⊑ g <=> FLOOKUP g x = SOME y /\ f \\ x ⊑ g)
Proof
rw [SUBMAP_FUPDATE, FLOOKUP_DEF]
\\ EQ_TAC \\ rw []
\\ fs [SUBMAP_DEF]
\\ fs [DOMSUB_FAPPLY_THM]
QED
Definition has_bools_def:
has_bools genv ⇔
FLOOKUP genv ((true_tag, SOME bool_id), 0n) = SOME (TypeStamp "True" bool_type_num) ∧
FLOOKUP genv ((false_tag, SOME bool_id), 0n) = SOME (TypeStamp "False" bool_type_num)
End
Definition has_lists_def:
has_lists genv ⇔
FLOOKUP genv ((cons_tag, SOME list_id), 2n) = SOME (TypeStamp "::" list_type_num) ∧
FLOOKUP genv ((nil_tag, SOME list_id), 0n) = SOME (TypeStamp "[]" list_type_num)
End
Definition has_exns_def:
has_exns genv ⇔
FLOOKUP genv ((div_tag, NONE), 0n) = SOME div_stamp ∧
FLOOKUP genv ((chr_tag, NONE), 0n) = SOME chr_stamp ∧
FLOOKUP genv ((subscript_tag, NONE), 0n) = SOME subscript_stamp ∧
FLOOKUP genv ((bind_tag, NONE), 0n) = SOME bind_stamp
End
Definition genv_c_ok_def:
genv_c_ok genv_c ⇔
has_bools genv_c ∧
has_exns genv_c ∧
has_lists genv_c ∧
(!cn1 cn2 l1 l2 stamp1 stamp2.
FLOOKUP genv_c (cn1,l1) = SOME stamp1 ∧
FLOOKUP genv_c (cn2,l2) = SOME stamp2
⇒
(ctor_same_type (SOME stamp1) (SOME stamp2) ⇔ ctor_same_type (SOME cn1) (SOME cn2))) ∧
(!cn1 cn2 l1 l2 stamp.
FLOOKUP genv_c (cn1,l1) = SOME stamp ∧
FLOOKUP genv_c (cn2,l2) = SOME stamp
⇒
cn1 = cn2 ∧ l1 = l2)
End
Definition genv_c_tys_ok_def:
genv_c_tys_ok genv_c genv_tys ⇔
!cn ty_id arity.
((cn, SOME ty_id), arity) IN FDOM genv_c ⇒
?ctors. FLOOKUP genv_tys ty_id = SOME ctors ∧
MEM (cn, arity) ctors
End
Inductive v_rel:
(!genv lit.
v_rel genv ((Litv lit):semanticPrimitives$v) ((Litv lit):flatSem$v)) ∧
(!genv cn cn' vs vs'.
LIST_REL (v_rel genv) vs vs' ∧
FLOOKUP genv.c (cn', LENGTH vs) = SOME cn
⇒
v_rel genv (Conv (SOME cn) vs) (Conv (SOME cn') vs')) ∧
(!genv vs vs'.
LIST_REL (v_rel genv) vs vs'
⇒
v_rel genv (Conv NONE vs) (Conv NONE vs')) ∧
(!genv comp_map env env_v_local x e env_v_local' t ts.
env_rel genv env_v_local env_v_local'.v ∧
global_env_inv genv comp_map (set (MAP FST env_v_local'.v)) env ∧
LENGTH ts = LENGTH env_v_local'.v + 1
⇒
v_rel genv
(Closure (env with v := nsAppend env_v_local env.v) x e)
(Closure env_v_local' x
(compile_exp t
(comp_map with v := bind_locals ts (x::MAP FST env_v_local'.v) comp_map.v)
e))) ∧
(* For expression level let recs *)
(!genv comp_map env env_v_local funs x env_v_local' t ts.
env_rel genv env_v_local env_v_local'.v ∧
global_env_inv genv comp_map (set (MAP FST env_v_local'.v)) env ∧
LENGTH ts = LENGTH funs + LENGTH env_v_local'.v
⇒
v_rel genv
(Recclosure (env with v := nsAppend env_v_local env.v) funs x)
(Recclosure env_v_local'
(compile_funs t
(comp_map with v := bind_locals ts (MAP FST funs++MAP FST env_v_local'.v) comp_map.v) funs)
x)) ∧
(* For top-level let recs *)
(!genv comp_map env funs flat_env x y e new_vars t1 t2.
MAP FST new_vars = MAP FST (REVERSE funs) ∧
global_env_inv genv comp_map {} env ∧
flat_env.v = [] ∧
find_recfun x funs = SOME (y, e) ∧
(* A syntactic way of relating the recursive function environment, rather
* than saying that they build v_rel related environments, which looks to
* require step-indexing *)
(!x. x ∈ set (MAP FST funs) ⇒
?n y e t1 t2 t3.
ALOOKUP new_vars x = SOME (Glob t1 n) ∧
n < LENGTH genv.v ∧
find_recfun x funs = SOME (y,e) ∧
EL n genv.v =
SOME (Closure flat_env y
(compile_exp t2 (comp_map with v := nsBindList ((y, Local t3 y)::new_vars) comp_map.v) e)))
⇒
v_rel genv
(Recclosure env funs x)
(Closure flat_env y
(compile_exp t1
(comp_map with v := nsBindList ((y, Local t2 y)::new_vars) comp_map.v)
e))) ∧
(!genv loc b.
v_rel genv (Loc b loc) (Loc b (loc + 1))) ∧
(!genv vs vs'.
LIST_REL (v_rel genv) vs vs'
⇒
v_rel genv (Vectorv vs) (Vectorv vs')) ∧
(* For floating-point value trees *)
(! genv fp w.
compress_word fp = w ==>
v_rel genv (FP_WordTree fp) (Litv (Word64 w))) /\
(!(genv:global_env) fp.
FLOOKUP (genv.c) (((if (compress_bool fp) then true_tag else false_tag),SOME bool_id), 0) =
SOME (TypeStamp (if (compress_bool fp) then "True" else "False") bool_type_num)
⇒
v_rel genv (FP_BoolTree fp) (Boolv (compress_bool fp))) ∧
(!genv.
env_rel genv nsEmpty []) ∧
(!genv x v env env' v'.
env_rel genv env env' ∧
v_rel genv v v'
⇒
env_rel genv (nsBind x v env) ((x,v')::env')) ∧
(!genv comp_map shadowers env.
(!x v.
x ∉ IMAGE Short shadowers ∧
nsLookup env.v x = SOME v
⇒
?n v' t.
nsLookup comp_map.v x = SOME (Glob t n) ∧
n < LENGTH genv.v ∧
EL n genv.v = SOME v' ∧
v_rel genv v v') ∧
(!x arity stamp.
nsLookup env.c x = SOME (arity, stamp) ⇒
∃cn ty_gp. nsLookup comp_map.c x = SOME (cn, ty_gp) ∧
FLOOKUP genv.c ((cn, OPTION_MAP FST ty_gp), arity) = SOME stamp ∧
(! ty_id ctors. ty_gp = SOME (ty_id, ctors) ⇒
FLOOKUP genv.tys ty_id = SOME ctors)
)
⇒
global_env_inv genv comp_map shadowers env)
End
(*
Theorem v_rel_eqns:
(!genv l v.
v_rel genv (Litv l) v ⇔
(v = Litv l)) ∧
(!genv vs v.
v_rel genv (Conv cn vs) v ⇔
?vs' cn'.
LIST_REL (v_rel genv) vs vs' ∧
v = Conv cn' vs' ∧
case cn of
| NONE => cn' = NONE
| SOME cn =>
?cn2. cn' = SOME cn2 ∧ FLOOKUP genv.c (cn2, LENGTH vs) = SOME cn) ∧
(!genv l v b.
v_rel genv (Loc b l) v ⇔
(v = Loc b l)) ∧
(!genv vs v.
v_rel genv (Vectorv vs) v ⇔
?vs'. LIST_REL (v_rel genv) vs vs' ∧ (v = Vectorv vs')) ∧
(!genv fp v.
v_rel genv (FP_WordTree fp) v <=>
v = Litv (Word64 (compress_word fp))) /\
(! genv fp v cn.
v_rel genv (FP_BoolTree fp) v <=>
FLOOKUP (genv.c) (((if (compress_bool fp) then true_tag else false_tag),SOME bool_id), 0) =
SOME (TypeStamp (if (compress_bool fp) then "True" else "False") bool_type_num) /\
v = Boolv (compress_bool fp)) /\
(!genv env'.
env_rel genv nsEmpty env' ⇔
env' = []) ∧
(!genv x v env env'.
env_rel genv (nsBind x v env) env' ⇔
?v' env''. v_rel genv v v' ∧ env_rel genv env env'' ∧ env' = ((x,v')::env'')) ∧
(!genv comp_map shadowers env.
global_env_inv genv comp_map shadowers env ⇔
(!x v.
x ∉ IMAGE Short shadowers ∧
nsLookup env.v x = SOME v
⇒
?n v' t.
nsLookup comp_map.v x = SOME (Glob t n) ∧
n < LENGTH genv.v ∧
EL n genv.v = SOME v' ∧
v_rel genv v v') ∧
(!x arity stamp.
nsLookup env.c x = SOME (arity, stamp) ⇒
∃cn. nsLookup comp_map.c x = SOME cn ∧
FLOOKUP genv.c (cn,arity) = SOME stamp))
Proof
srw_tac[][semanticPrimitivesTheory.Boolv_def,flatSemTheory.Boolv_def] >>
srw_tac[][Once v_rel_cases] >>
srw_tac[][Q.SPECL[`genv`,`nsEmpty`](CONJUNCT1(CONJUNCT2 v_rel_cases))] >>
srw_tac[][flatSemTheory.Boolv_def, semanticPrimitivesTheory.Boolv_def] >>
every_case_tac >>
fs [genv_c_ok_def, has_bools_def] >>
TRY eq_tac >>
rw [] >>
metis_tac []
*)
Triviality v_rel_eqns =
[``v_rel genv (Litv l) v``, ``v_rel genv (Conv cn vs) v``,
``v_rel genv (Loc b l) v``, ``v_rel genv (Vectorv vs) v``,
``env_rel genv nsEmpty env'``, ``env_rel genv (nsBind x v env) env'``,
``v_rel genv (Env e id) v``,
“v_rel genv (FP_WordTree fp) v”,
“v_rel genv (FP_BoolTree fp) v”]
|> map (SIMP_CONV (srw_ss ()) [Once v_rel_cases])
|> map GEN_ALL
|> LIST_CONJ
Theorem v_rel_more_eqns =
[``v_rel genv (Closure env nm exp) v``,
``v_rel genv (Recclosure env funs x) v``]
|> map (SIMP_CONV (srw_ss ()) [Once v_rel_cases])
|> map GEN_ALL
|> LIST_CONJ
|> CONJ v_rel_eqns
Theorem v_rel_global_eqn = SIMP_CONV (srw_ss ()) [Once v_rel_cases]
``global_env_inv genv comp_map shadowers env``
Theorem env_rel_LIST_REL:
!xs ys. env_rel genv (alist_to_ns xs) ys <=>
LIST_REL (\x y. FST x = FST y /\ v_rel genv (SND x) (SND y)) xs ys
Proof
Induct \\ simp [Once v_rel_cases]
\\ simp [FORALL_PROD, PULL_EXISTS]
\\ rw []
\\ EQ_TAC
\\ simp [PULL_EXISTS, FORALL_PROD]
QED
Triviality env_rel_dom:
!genv env env'.
env_rel genv env env'
⇒
?l. env = alist_to_ns l ∧ MAP FST l = MAP FST env'
Proof
induct_on `env'` >>
simp [Once v_rel_cases] >>
rw [] >>
first_x_assum drule >>
rw [] >>
rw_tac list_ss [GSYM alist_to_ns_cons] >>
prove_tac [MAP, FST]
QED
Triviality env_rel_lookup:
!genv env x v env'.
ALOOKUP env x = SOME v ∧
env_rel genv (alist_to_ns env) env'
⇒
?v'.
v_rel genv v v' ∧
ALOOKUP env' x = SOME v'
Proof
induct_on `env'` >>
simp [] >>
simp [Once v_rel_cases] >>
rw [] >>
rw [] >>
fs [] >>
rw [] >>
Cases_on `env` >>
TRY (PairCases_on `h`) >>
fs [alist_to_ns_cons] >>
rw [] >>
metis_tac []
QED
Triviality env_rel_append:
!genv env1 env2 env1' env2'.
env_rel genv env1 env1' ∧
env_rel genv env2 env2'
⇒
env_rel genv (nsAppend env1 env2) (env1'++env2')
Proof
induct_on `env1'` >>
rw []
>- (
`env1 = nsEmpty` by fs [Once v_rel_cases] >>
rw []) >>
qpat_x_assum `env_rel _ _ (_::_)` mp_tac >>
simp [Once v_rel_cases] >>
rw [] >>
rw [] >>
simp [Once v_rel_cases]
QED
Triviality env_rel_one:
env_rel genv (nsBind a b nsEmpty) xs <=>
?v. xs = [(a, v)] /\ v_rel genv b v
Proof
simp [Once v_rel_cases]
\\ Cases_on `xs` \\ simp []
\\ simp [Once v_rel_cases]
\\ metis_tac []
QED
Theorem env_rel_bind_one = env_rel_append
|> Q.SPECL [`genv`, `nsBind a b nsEmpty`, `env2`, `[(c, d)]`]
|> GEN_ALL
|> SIMP_RULE (srw_ss ()) [env_rel_one]
Triviality env_rel_el:
!genv env env_i1.
env_rel genv (alist_to_ns env) env_i1 ⇔
LENGTH env = LENGTH env_i1 ∧ !n. n < LENGTH env ⇒ (FST (EL n env) = FST (EL n env_i1)) ∧ v_rel genv (SND (EL n env)) (SND (EL n env_i1))
Proof
induct_on `env` >>
srw_tac[][v_rel_eqns] >>
PairCases_on `h` >>
srw_tac[][v_rel_eqns] >>
eq_tac >>
srw_tac[][] >>
srw_tac[][]
>- (cases_on `n` >>
full_simp_tac(srw_ss())[])
>- (cases_on `n` >>
full_simp_tac(srw_ss())[])
>- (cases_on `env_i1` >>
full_simp_tac(srw_ss())[] >>
FIRST_ASSUM (qspecl_then [`0`] mp_tac) >>
SIMP_TAC (srw_ss()) [] >>
srw_tac[][] >>
qexists_tac `SND h` >>
srw_tac[][] >>
FIRST_X_ASSUM (qspecl_then [`SUC n`] mp_tac) >>
srw_tac[][])
QED
Definition subglobals_def:
subglobals g1 g2 ⇔
LENGTH g1 ≤ LENGTH g2 ∧
!n. n < LENGTH g1 ∧ IS_SOME (EL n g1) ⇒ EL n g1 = EL n g2
End
Triviality subglobals_refl:
!g. subglobals g g
Proof
rw [subglobals_def]
QED
Triviality subglobals_trans:
!g1 g2 g3. subglobals g1 g2 ∧ subglobals g2 g3 ⇒ subglobals g1 g3
Proof
rw [subglobals_def] >>
res_tac >>
fs []
QED
Triviality subglobals_refl_append:
!g1 g2 g3.
subglobals (g1 ++ g2) (g1 ++ g3) = subglobals g2 g3 ∧
(LENGTH g2 = LENGTH g3 ⇒ subglobals (g2 ++ g1) (g3 ++ g1) = subglobals g2 g3)
Proof
rw [subglobals_def] >>
eq_tac >>
rw []
>- (
first_x_assum (qspec_then `n + LENGTH (g1:'a option list)` mp_tac) >>
rw [EL_APPEND_EQN])
>- (
first_x_assum (qspec_then `n - LENGTH (g1:'a option list)` mp_tac) >>
rw [EL_APPEND_EQN] >>
fs [EL_APPEND_EQN])
>- (
first_x_assum (qspec_then `n` mp_tac) >>
rw [EL_APPEND_EQN])
>- (
Cases_on `n < LENGTH g3` >>
fs [EL_APPEND_EQN] >>
rfs [] >>
fs [])
QED
Triviality v_rel_weakening:
(!genv v v'.
v_rel genv v v'
⇒
!genv'. genv.c = genv'.c ∧ genv.tys = genv'.tys ∧
subglobals genv.v genv'.v ⇒ v_rel genv' v v') ∧
(!genv env env'.
env_rel genv env env'
⇒
!genv'. genv.c = genv'.c ∧ genv.tys = genv'.tys ∧
subglobals genv.v genv'.v ⇒ env_rel genv' env env') ∧
(!genv comp_map shadowers env.
global_env_inv genv comp_map shadowers env
⇒
!genv'. genv.c = genv'.c ∧ genv.tys = genv'.tys ∧
subglobals genv.v genv'.v ⇒ global_env_inv genv' comp_map shadowers env)
Proof
ho_match_mp_tac v_rel_ind >>
srw_tac[][v_rel_eqns, subglobals_def] >> fs[]
>- fs [LIST_REL_EL_EQN]
>- fs [LIST_REL_EL_EQN]
>- (srw_tac[][Once v_rel_cases] >>
MAP_EVERY qexists_tac [`comp_map`, `env`, `env'`, `t`, `ts`] >>
full_simp_tac(srw_ss())[FDOM_FUPDATE_LIST, SUBSET_DEF, v_rel_eqns])
>- (srw_tac[][Once v_rel_cases] >>
MAP_EVERY qexists_tac [`comp_map`, `env`, `env'`, `t`,`ts`] >>
full_simp_tac(srw_ss())[FDOM_FUPDATE_LIST, SUBSET_DEF, v_rel_eqns])
>- (srw_tac[][Once v_rel_cases] >>
MAP_EVERY qexists_tac [`comp_map`, `new_vars`, `t1`, `t2`] >>
full_simp_tac(srw_ss())[FDOM_FUPDATE_LIST, SUBSET_DEF, v_rel_eqns, EL_APPEND1] >>
srw_tac[][] >>
res_tac >>
qexists_tac `n` >>
srw_tac[][EL_APPEND1] >>
map_every qexists_tac [`t2`,`t3`] >>
rw [] >>
metis_tac [IS_SOME_DEF])
>- fs [LIST_REL_EL_EQN]
>- (
rw [v_rel_global_eqn] >>
res_tac >>
rw [] >>
res_tac >>
rveq >> fs [] >>
rveq >> fs [] >>
rfs []
)
QED
Triviality v_rel_weakening2:
(!genv v v'.
v_rel genv v v'
⇒
∀gc. genv.c ⊑ genv'.c ∧ genv.tys ⊑ genv'.tys ∧ genv.v = genv'.v ⇒
v_rel genv' v v') ∧
(!genv env env'.
env_rel genv env env'
⇒
∀gc. genv.c ⊑ genv'.c ∧ genv.tys ⊑ genv'.tys ∧ genv.v = genv'.v ⇒
env_rel genv' env env') ∧
(!genv comp_map shadowers env.
global_env_inv genv comp_map shadowers env
⇒
∀gc. genv.c ⊑ genv'.c ∧ genv.tys ⊑ genv'.tys ∧ genv.v = genv'.v ⇒
global_env_inv genv' comp_map shadowers env)
Proof
ho_match_mp_tac v_rel_ind >>
srw_tac[][v_rel_eqns] >>
fs [SUBMAP_FLOOKUP_EQN]
>- fs [LIST_REL_EL_EQN]
>- fs [LIST_REL_EL_EQN]
>- (simp [Once v_rel_cases] >> metis_tac [])
>- (simp [Once v_rel_cases] >> metis_tac [])
>- (simp [Once v_rel_cases] >>
MAP_EVERY qexists_tac [`comp_map`, `new_vars`, `t1`, `t2`] >>
simp []
)
>- fs [LIST_REL_EL_EQN]
>- (
fs [v_rel_global_eqn] >>
rw [] >>
res_tac >>
fs [] >>
metis_tac []
)
QED
Triviality drestrict_lem:
f1 SUBMAP f2 ⇒ DRESTRICT f2 (COMPL (FDOM f1)) ⊌ f1 = f2
Proof
rw [FLOOKUP_EXT, FUN_EQ_THM, FLOOKUP_FUNION] >>
every_case_tac >>
fs [FLOOKUP_DRESTRICT, SUBMAP_DEF] >>
fs [FLOOKUP_DEF] >>
rw [] >>
metis_tac []
QED
Theorem v_rel_weak:
!genv v v' genv'.
v_rel genv v v' ∧
genv.c ⊑ genv'.c ∧
genv.tys ⊑ genv'.tys ∧
subglobals genv.v genv'.v
⇒
v_rel genv' v v'
Proof
rw [] >>
FIRST (map drule (CONJUNCTS v_rel_weakening)) >>
disch_then (qspec_then `genv with v := genv'.v` mp_tac) >>
rw [] >>
FIRST (map drule (CONJUNCTS v_rel_weakening2)) >>
disch_then irule >>
simp []
QED
Theorem env_rel_weak:
!genv env env' genv'.
env_rel genv env env' ∧
genv.c ⊑ genv'.c ∧
genv.tys ⊑ genv'.tys ∧
subglobals genv.v genv'.v
⇒
env_rel genv' env env'
Proof
rw [] >>
FIRST (map drule (CONJUNCTS v_rel_weakening)) >>
disch_then (qspec_then `genv with v := genv'.v` mp_tac) >>
rw [] >>
FIRST (map drule (CONJUNCTS v_rel_weakening2)) >>
disch_then irule >>
simp []
QED
Theorem global_env_inv_weak:
!genv comp_map shadowers env genv'.
global_env_inv genv comp_map shadowers env ∧
genv.c ⊑ genv'.c ∧
genv.tys ⊑ genv'.tys ∧
subglobals genv.v genv'.v
⇒
global_env_inv genv' comp_map shadowers env
Proof
rw [] >>
FIRST (map drule (CONJUNCTS v_rel_weakening)) >>
disch_then (qspec_then `genv with v := genv'.v` mp_tac) >>
rw [] >>
FIRST (map drule (CONJUNCTS v_rel_weakening2)) >>
disch_then irule >>
simp []
QED
Inductive result_rel:
(∀genv v v'.
f genv v v'
⇒
result_rel f genv (Rval v) (Rval v')) ∧
(∀genv v v'.
v_rel genv v v'
⇒
result_rel f genv (Rerr (Rraise v)) (Rerr (Rraise v'))) ∧
(!genv a.
result_rel f genv (Rerr (Rabort a)) (Rerr (Rabort a)))
End
Triviality result_rel_eqns:
(!genv v r.
result_rel f genv (Rval v) r ⇔
?v'. f genv v v' ∧ r = Rval v') ∧
(!genv v r.
result_rel f genv (Rerr (Rraise v)) r ⇔
?v'. v_rel genv v v' ∧ r = Rerr (Rraise v')) ∧
(!genv v r a.
result_rel f genv (Rerr (Rabort a)) r ⇔
r = Rerr (Rabort a))
Proof
srw_tac[][result_rel_cases] >>
metis_tac []
QED
Inductive sv_rel:
(!genv v v'.
v_rel genv v v'
⇒
sv_rel genv (Refv v) (Refv v')) ∧
(!genv w.
sv_rel genv (W8array w) (W8array w)) ∧
(!genv vs vs'.
LIST_REL (v_rel genv) vs vs'
⇒
sv_rel genv (Varray vs) (Varray vs'))
End
Triviality sv_rel_weak:
!genv sv sv' genv'.
sv_rel genv sv sv' ∧
genv.c ⊑ genv'.c ∧
genv.tys ⊑ genv'.tys ∧
subglobals genv.v genv'.v
⇒
sv_rel genv' sv sv'
Proof
srw_tac[][sv_rel_cases] >>
metis_tac [v_rel_weak, LIST_REL_EL_EQN]
QED
Inductive s_rel:
(!genv s s'.
~ NULL s'.refs ∧
LIST_REL (sv_rel genv) s.refs (TL s'.refs) ∧
s.fp_state.canOpt = Strict ∧
~ s.fp_state.real_sem ∧
s.clock = s'.clock ∧
s.ffi = s'.ffi ∧
s'.c = FDOM genv.c
⇒
s_rel genv s s')
End
Inductive env_all_rel:
(!genv map env_v_local env env' locals.
(?l. env_v_local = alist_to_ns l ∧ MAP FST l = locals) ∧
global_env_inv genv map (set locals) env ∧
env_rel genv env_v_local env'
⇒
env_all_rel genv map
<| c := env.c; v := nsAppend env_v_local env.v |>
<| v := env' |>
locals)
End
Triviality env_all_rel_weak:
!genv map locals env env' genv'.
env_all_rel genv map env env' locals ∧
genv.c ⊑ genv'.c ∧
genv.tys ⊑ genv'.tys ∧
subglobals genv.v genv'.v
⇒
env_all_rel genv' map env env' locals
Proof
rw [env_all_rel_cases] >>
imp_res_tac env_rel_weak >>
imp_res_tac global_env_inv_weak >>
MAP_EVERY qexists_tac [`alist_to_ns l`, `env''`, `env'''`] >>
rw [] >>
metis_tac [SUBMAP_FDOM_SUBSET, SUBSET_TRANS]
QED
Definition match_result_rel_def:
(match_result_rel genv env' (Match env) (Match env_i1) =
?env''. env = env'' ++ env' ∧ env_rel genv (alist_to_ns env'') env_i1) ∧
(match_result_rel genv env' No_match No_match = T) ∧
(match_result_rel genv env' Match_type_error _ = T) ∧
(match_result_rel genv env' _ _ = F)
End
Theorem match_result_rel_imp:
match_result_rel genv env m1 m2 ==>
(m1 = Match_type_error \/ (m1 = No_match /\ m2 = No_match)
\/ (?env1 env2. m1 = Match env1 /\ m2 = Match env2))
Proof
Cases_on `m1` \\ Cases_on `m2` \\ simp [match_result_rel_def]
QED
(* semantic functions respect relation *)
Triviality do_eq:
!genv. genv_c_ok genv.c ⇒
(!v1 v2 r v1_i1 v2_i1.
do_eq v1 v2 = r ∧
v_rel genv v1 v1_i1 ∧
v_rel genv v2 v2_i1
⇒
do_eq v1_i1 v2_i1 = r) ∧
(!vs1 vs2 r vs1_i1 vs2_i1.
do_eq_list vs1 vs2 = r ∧
LIST_REL (v_rel genv) vs1 vs1_i1 ∧
LIST_REL (v_rel genv) vs2 vs2_i1
⇒
do_eq_list vs1_i1 vs2_i1 = r)
Proof
ntac 2 strip_tac >>
ho_match_mp_tac semanticPrimitivesTheory.do_eq_ind >>
rpt strip_tac >>
fs [Boolv_def, semanticPrimitivesTheory.do_eq_def, flatSemTheory.do_eq_def, v_rel_more_eqns] >>
rveq >> fs [] >>
rpt (irule COND_CONG >> rpt strip_tac) >>
imp_res_tac LIST_REL_LENGTH >>
fs [flatSemTheory.ctor_same_type_def,
semanticPrimitivesTheory.ctor_same_type_def] >>
TRY (
rename1 ‘v_rel _ (Real r1) _’
>> qpat_x_assum ‘v_rel _ (Real _) _’ $ assume_tac o SIMP_RULE std_ss [Once v_rel_cases] >> gs[])
>~ [‘_ = Eq_val (compress_bool _ ⇔ compress_bool _)’]
>- (every_case_tac >> gs[]) >>
TRY (
rename1 ‘compress_bool v2’ >>
fs[semanticPrimitivesTheory.Boolv_def, flatSemTheory.Boolv_def, do_eq_def] >>
TRY (Cases_on `cn''` ORELSE Cases_on `cn'`) >> fs[] >>
TRY (fs[flatSemTheory.ctor_same_type_def, semanticPrimitivesTheory.ctor_same_type_def] >> NO_TAC) >>
rveq >> Cases_on ‘compress_bool v2’ >> gs[] >>
((rename1 `TypeStamp "True" bool_type_num = ts /\ vs = []` >> Cases_on `ts = TypeStamp "True" bool_type_num`) ORELSE
(rename1 `TypeStamp "False" bool_type_num = ts /\ vs = []` >> Cases_on `ts = TypeStamp "False" bool_type_num`)) >>
Cases_on `vs = []` >> rveq >> fs[genv_c_ok_def, has_bools_def] >> rveq >>
TRY (res_tac >> fs[ctor_same_type_def, semanticPrimitivesTheory.ctor_same_type_def] >> EVAL_TAC >> NO_TAC) >>
(`(true_tag, SOME bool_id) <> (q,r)` by (CCONTR_TAC >> fs[]) ORELSE
`(false_tag, SOME bool_id) <> (q,r)` by (CCONTR_TAC >> fs[])) >>
fs[ctor_same_type_def] >>
COND_CASES_TAC >> gs[] >> rveq >> res_tac
>> Cases_on ‘ts’ >> gs[semanticPrimitivesTheory.ctor_same_type_def, ctor_same_type_def, same_type_def]
) >>
TRY every_case_tac >>
gs[lit_same_type_def] >>
metis_tac [SOME_11, genv_c_ok_def
|> SIMP_RULE (srw_ss()) [semanticPrimitivesTheory.ctor_same_type_def]]
QED
Theorem genv_lookup_nil:
genv_c_ok genv_c ==>
(FLOOKUP genv_c cn = SOME (TypeStamp "[]" list_type_num)
<=> cn = ((nil_tag, SOME list_id), 0))
Proof
Cases_on `cn`
\\ simp [genv_c_ok_def, has_lists_def]
\\ metis_tac []
QED
Theorem genv_lookup_cons:
genv_c_ok genv_c ==>
(FLOOKUP genv_c cn = SOME (TypeStamp "::" list_type_num)
<=> cn = ((cons_tag, SOME list_id), 2))
Proof
Cases_on `cn`
\\ simp [genv_c_ok_def, has_lists_def]
\\ metis_tac []
QED
Triviality v_to_char_list:
!genv. genv_c_ok genv.c ⇒
!v1 v2 vs1.
v_rel genv v1 v2 ∧
v_to_char_list v1 = SOME vs1
⇒
v_to_char_list v2 = SOME vs1
Proof
ntac 2 strip_tac >>
ho_match_mp_tac semanticPrimitivesTheory.v_to_char_list_ind >>
srw_tac[][semanticPrimitivesTheory.v_to_char_list_def] >>
every_case_tac >>
full_simp_tac(srw_ss())[v_rel_more_eqns, flatSemTheory.v_to_char_list_def] >>
imp_res_tac genv_lookup_nil >>
imp_res_tac genv_lookup_cons >>
fs [] >>
rw [flatSemTheory.v_to_char_list_def]
QED
Triviality v_to_list:
!genv. genv_c_ok genv.c ⇒
!v1 v2 vs1.
v_rel genv v1 v2 ∧
v_to_list v1 = SOME vs1
⇒
?vs2.
v_to_list v2 = SOME vs2 ∧
LIST_REL (v_rel genv) vs1 vs2
Proof
ntac 2 strip_tac >>
ho_match_mp_tac semanticPrimitivesTheory.v_to_list_ind >>
srw_tac[][semanticPrimitivesTheory.v_to_list_def] >>
every_case_tac >>
full_simp_tac(srw_ss())[v_rel_eqns, flatSemTheory.v_to_list_def] >>
srw_tac[][] >>
imp_res_tac genv_lookup_nil >>
imp_res_tac genv_lookup_cons >>
fs [] >>
rw [flatSemTheory.v_to_list_def] >>
res_tac >>
fs []
QED
Triviality vs_to_string:
∀v1 v2 s.
LIST_REL (v_rel genv) v1 v2 ⇒
vs_to_string v1 = SOME s ⇒
vs_to_string v2 = SOME s
Proof
ho_match_mp_tac semanticPrimitivesTheory.vs_to_string_ind
\\ rw[semanticPrimitivesTheory.vs_to_string_def,vs_to_string_def]
\\ fs[v_rel_eqns]
\\ pop_assum mp_tac
\\ TOP_CASE_TAC \\ strip_tac \\ rveq \\ fs[]
\\ rw[vs_to_string_def]
QED
Triviality v_rel_lems:
!genv. genv_c_ok genv.c ⇒
(!b. v_rel genv (Boolv b) (Boolv b)) ∧
v_rel genv div_exn_v div_exn_v ∧
v_rel genv chr_exn_v chr_exn_v ∧
v_rel genv bind_exn_v bind_exn_v ∧
v_rel genv sub_exn_v subscript_exn_v
Proof
rw [semanticPrimitivesTheory.div_exn_v_def, flatSemTheory.div_exn_v_def,
semanticPrimitivesTheory.chr_exn_v_def, flatSemTheory.chr_exn_v_def,
semanticPrimitivesTheory.bind_exn_v_def, flatSemTheory.bind_exn_v_def,
semanticPrimitivesTheory.sub_exn_v_def, flatSemTheory.subscript_exn_v_def,
v_rel_eqns, genv_c_ok_def, has_exns_def, has_bools_def,
semanticPrimitivesTheory.Boolv_def, flatSemTheory.Boolv_def] >>
every_case_tac >>
simp [v_rel_eqns]
QED
Theorem list_to_v_v_rel:
!xs ys.
has_lists genv.c ∧ LIST_REL (v_rel genv) xs ys ⇒
v_rel genv (list_to_v xs) (list_to_v ys)
Proof
Induct >>
rw [] >>
fs [LIST_REL_EL_EQN, flatSemTheory.list_to_v_def, has_lists_def,
v_rel_eqns, semanticPrimitivesTheory.list_to_v_def]
QED
Theorem LIST_REL_IMP_EL2: (* TODO: move *)
!P xs ys. LIST_REL P xs ys ==> !i. i < LENGTH ys ==> P (EL i xs) (EL i ys)
Proof
Induct_on `xs` \\ fs [PULL_EXISTS] \\ rw [] \\ Cases_on `i` \\ fs []
QED
Theorem LIST_REL_IMP_EL: (* TODO: move *)
!P xs ys. LIST_REL P xs ys ==> !i. i < LENGTH xs ==> P (EL i xs) (EL i ys)
Proof
Induct_on `xs` \\ fs [PULL_EXISTS] \\ rw [] \\ Cases_on `i` \\ fs []
QED
Triviality NOT_NULL_EQ:
(~ NULL xs) = (?y ys. xs = CONS y ys)
Proof
Cases_on `xs` \\ simp []
QED
val s_i1 = ``s_i1 : ('f_orac_st, 'ffi) flatSem$state``;
val s1_i1 = mk_var ("s1_i1", type_of s_i1);
val do_app = time Q.prove (
`!genv s1 s2 op vs r ^s1_i1 vs_i1.
do_app s1 op vs = SOME (s2, r) ∧
LIST_REL (sv_rel genv) (FST s1) (TL s1_i1.refs) ∧
~ NULL s1_i1.refs ∧
LIST_REL (v_rel genv) vs vs_i1 ∧
SND s1 = s1_i1.ffi ∧
genv_c_ok genv.c ∧
op ≠ AallocEmpty ∧
getOpClass op ≠ Reals ∧
op ≠ Env_id
⇒
∃r_i1 s2_i1.
LIST_REL (sv_rel genv) (FST s2) (TL s2_i1.refs) ∧
~ NULL s2_i1.refs ∧
SND s2 = s2_i1.ffi ∧
s1_i1.globals = s2_i1.globals ∧
TAKE 1 s1_i1.refs = TAKE 1 s2_i1.refs ∧
result_rel v_rel genv r r_i1 ∧
do_app s1_i1 (astOp_to_flatOp op) vs_i1 = SOME (s2_i1, r_i1)`,
rpt gen_tac >>
Cases_on `s1` >>
Cases_on `s1_i1.refs` >> simp [] >>
Cases_on `s1_i1` >>
Cases_on `op = ConfigGC` >-
(simp [astOp_to_flatOp_def] >>
srw_tac[][semanticPrimitivesPropsTheory.do_app_cases, flatSemTheory.do_app_def] >>
full_simp_tac(srw_ss())[v_rel_eqns, result_rel_cases, Unitv_def]) >>
pop_assum mp_tac >>
Cases_on `op` >>
simp [astOp_to_flatOp_def, astTheory.getOpClass_def]
>- ((* Opn *)
srw_tac[][semanticPrimitivesPropsTheory.do_app_cases, flatSemTheory.do_app_def] >>