-
Notifications
You must be signed in to change notification settings - Fork 4
/
quotient_llistScript.sml
166 lines (155 loc) · 3.83 KB
/
quotient_llistScript.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
open bossLib boolLib;
open HolKernel llistTheory listTheory quotientLib pure_miscTheory;
val _ = new_theory "quotient_llist";
Triviality LMAP_id:
LMAP (\x. x) = \x. x
Proof
irule EQ_EXT >>
irule LLIST_EQ >>
rw[] >>
Cases_on `x` >> gvs[LMAP]
QED
Theorem llist_map_I:
LMAP I = I
Proof
rw [I_def, LMAP_id]
QED
Theorem llist_rel_equality:
llist_rel $= = $=
Proof
irule EQ_EXT >> rw[] >>
irule EQ_EXT >> rw[] >>
rename1 `llist_rel _ a b` >>
fs[llist_rel_def] >>
EQ_TAC >> rw[] >> gvs[] >>
rw[LNTH_EQ] >>
Cases_on `LNTH n a`
>- (
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
) >>
reverse (Cases_on `LNTH n b`) >> gvs[]
>- (
first_x_assum irule >>
goal_assum drule >> simp[]
)
>- (
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
)
QED
Theorem llist_rel_REFL:
∀R.
(∀x y. R x y ⇔ R x = R y) ⇒
∀z. llist_rel R z z
Proof
simp [llist_rel_def, PULL_FORALL]
\\ rpt gen_tac
\\ map_every qid_spec_tac [‘x’, ‘y’, ‘z’, ‘i’]
\\ Induct \\ rw []
>- fs [LNTH]
\\ Q.ISPECL_THEN [‘z’] strip_assume_tac llist_CASES \\ fs []
QED
Triviality llist_rel_lemma:
∀R.
(∀x y. R x y ⇔ R x = R y) ⇒
∀z w.
llist_rel R z w ⇒ llist_rel R z = llist_rel R w
Proof
rw[] >> irule EQ_EXT >> fs[llist_rel_def] >>
rw[] >> EQ_TAC >> rw[] >>
rfs[] >> res_tac
>- (
qsuff_tac `∃ elem_z . LNTH i z = SOME elem_z`
>- (strip_tac >> gvs[]) >>
Cases_on `LNTH i z` >> gvs[] >>
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
)
>- (
qsuff_tac `∃ elem_w . LNTH i w = SOME elem_w`
>- (strip_tac >> gvs[]) >>
Cases_on `LNTH i w` >> gvs[] >>
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
)
QED
Theorem llist_EQUIV:
∀R. EQUIV R ⇒ EQUIV (llist_rel R)
Proof
gen_tac
\\ rw [EQUIV_def]
\\ eq_tac
>- metis_tac [llist_rel_lemma]
\\ rw [FUN_EQ_THM]
\\ irule llist_rel_REFL \\ fs []
QED
Theorem llist_QUOTIENT:
∀R abs rep.
QUOTIENT R abs rep ⇒
QUOTIENT (llist_rel R) (LMAP abs) (LMAP rep)
Proof
rpt strip_tac >>
rw[QUOTIENT_def]
>- (
drule QUOTIENT_ABS_REP >>
rw[LMAP_MAP, combinTheory.o_DEF, LMAP_id]
)
>- (
drule_then assume_tac QUOTIENT_REP_REFL >>
rw[llist_rel_def] >> fs[]
) >>
rw[llist_rel_def] >> EQ_TAC >> rw[] >> gvs[]
>- (
first_x_assum drule >>
Cases_on `LNTH i s` >> gvs[]
>- (
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
) >>
qpat_x_assum `QUOTIENT _ _ _` mp_tac >>
once_rewrite_tac [QUOTIENT_def] >>
rpt strip_tac >> res_tac
)
>- (
first_x_assum (drule_at (Pos last)) >>
Cases_on `LNTH i r` >> gvs[]
>- (
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
) >>
qpat_x_assum `QUOTIENT _ _ _` mp_tac >>
once_rewrite_tac [QUOTIENT_def] >>
rpt strip_tac >> res_tac
)
>- (
rw[LNTH_EQ] >>
Cases_on `LNTH n r`
>- (
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
) >>
Cases_on `LNTH n s`
>- (
imp_res_tac LNTH_NONE_LLENGTH >> gvs[] >>
imp_res_tac LNTH_LLENGTH_NONE >> gvs[]
) >>
fs[] >>
first_x_assum (drule_all_then assume_tac) >>
drule_then assume_tac QUOTIENT_REL >>
res_tac
)
>- (
`LLENGTH (LMAP abs r) = LLENGTH (LMAP abs s)` by fs[] >>
fs[LLENGTH_MAP]
)
>- (
rpt (first_x_assum drule_all >> strip_tac) >>
qpat_x_assum `QUOTIENT _ _ _` mp_tac >>
once_rewrite_tac [QUOTIENT_def] >> strip_tac >>
simp[] >>
`LNTH i (LMAP abs r) = LNTH i (LMAP abs s)` by metis_tac[] >>
pop_assum mp_tac >> simp[]
)
QED
val _ = export_theory ();