forked from CakeML/cakeml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cfHeapsLib.sml
171 lines (141 loc) · 4.58 KB
/
cfHeapsLib.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
(*
Conversions etc. over hprops
*)
structure cfHeapsLib :> cfHeapsLib =
struct
open preamble
open set_sepTheory helperLib ConseqConv
open cfHeapsBaseTheory cfHeapsTheory
open evarsConseqConvLib cfTacticsBaseLib cfHeapsBaseLib
infix 3 THEN_DCC
infix 3 ORELSE_DCC
(* Auxiliary functions *)
fun dest_F_pre_post tm =
(rator (rator tm), rand (rator tm), rand tm)
fun F_pre_post_conv conv_pre conv_post =
RAND_CONV conv_post THENC
RATOR_CONV (RAND_CONV conv_pre)
(* [hclean]; similar to [hpull], but for terms of the form [F H Q],
where F is local *)
fun prove_local_conseq_conv ctx =
let
val ctx = map
(* turn theorems of the context from [|- !x1..xn. P] to
[|- !x1..xn. T ==> P] *)
(CONV_RULE (STRIP_QUANT_CONV (REWR_CONV
(GSYM ConseqConvTheory.IMP_CLAUSES_TX))))
ctx
val ctx = (GSYM local_is_local) :: ctx
val ctx_cc = map (fn thm =>
CHANGED_CONSEQ_CONV (
CONSEQ_TOP_REWRITE_CONV ([], [thm], [])
CONSEQ_CONV_STRENGTHEN_direction)) ctx
in FIRST_CONSEQ_CONV ctx_cc end
fun hclean_one_conseq_conv_core ctx t =
let
val (_, pre, _) = dest_F_pre_post t
val hs = list_dest dest_star pre
fun rearrange_conv tm =
let val rest = filter (not o aconv tm) hs in
F_pre_post_conv (rearrange_star_conv tm rest) REFL
end
fun try_prove_local_cc t =
THEN_CONSEQ_CONV
(CONJ1_CONSEQ_CONV (prove_local_conseq_conv ctx))
(REWR_CONV ConseqConvTheory.AND_CLAUSES_TX) t
handle HOL_ERR _ => raise UNCHANGED
fun pull tm =
if is_cond tm then
SOME (
EVERY_CONSEQ_CONV [
rearrange_conv tm,
CONSEQ_TOP_HO_REWRITE_CONV
([], [hclean_prop, hclean_prop_single], [])
CONSEQ_CONV_STRENGTHEN_direction,
try_prove_local_cc
]
)
else if is_sep_exists tm then
SOME (
EVERY_CONSEQ_CONV [
rearrange_conv tm,
CONSEQ_TOP_HO_REWRITE_CONV
([], [hclean_exists_single], [])
CONSEQ_CONV_STRENGTHEN_direction,
CONJ2_CONSEQ_CONV
(REDEPTH_STRENGTHEN_CONSEQ_CONV (REDEPTH_CONV BETA_CONV)),
try_prove_local_cc
]
)
else
NONE
in
case find_map pull hs of
NONE => raise UNCHANGED
| SOME cc => cc t
end
fun hclean_one_dcc_core ctx =
STRENGTHEN_CONSEQ_CONV (hclean_one_conseq_conv_core ctx)
val hclean_setup_conv =
F_pre_post_conv (QCONV heap_clean_conv) REFL
fun hclean_one_conseq_conv ctx =
STRENGTHEN_CONSEQ_CONV hclean_setup_conv THEN_DCC
(hclean_one_dcc_core ctx)
fun hclean_conseq_conv ctx =
STRENGTHEN_CONSEQ_CONV hclean_setup_conv THEN_DCC
EXT_DEPTH_CONSEQ_CONV
(CONSEQ_CONV_get_context_congruences CONSEQ_CONV_FULL_CONTEXT)
CONSEQ_CONV_default_cache_opt NONE true
[(true, NONE, hclean_one_dcc_core)] ctx
val hclean_one = ASM_CONSEQ_CONV_TAC hclean_one_conseq_conv
val hclean = ASM_CONSEQ_CONV_TAC hclean_conseq_conv
(* demo:
g `is_local CF ==>
CF (H1 * emp * (H2 * SEP_EXISTS y. cond (P y)) * x ~~>> Refv xv * H3)
Q`
e strip_tac;
e (hclean_one \\ strip_tac);
e (hclean_one \\ strip_tac);
(* or alternatively *)
e strip_tac;
e hclean
g `CF (H * emp) Q : bool`
e hclean
g `CF (cond P * A * cond Q : hprop) (J:v -> hprop) : bool`
e hclean
*)
(** hchange *)
infix then_ecc
infix THEN_DCC
fun hchange_apply_cc lemma_th cont_ecc1 cont_ecc2 =
CONSEQ_TOP_REWRITE_CONV ([], [hchange_lemma], []) THEN_DCC
STRENGTHEN_CONSEQ_CONV (
ecc_conseq_conv (
(conj_ecc
(irule_ecc lemma_th)
(conj_ecc cont_ecc1 cont_ecc2)) then_ecc
hinst_ecc
)
)
(* todo: cf todo in xapply *)
val hcancel_cont_ecc =
lift_conseq_conv_ecc (hcancel_conseq_conv CONSEQ_CONV_STRENGTHEN_direction)
val hsimpl_cont_ecc =
lift_conseq_conv_ecc (hsimpl_conseq_conv CONSEQ_CONV_STRENGTHEN_direction)
val id_cont_ecc =
lift_conseq_conv_ecc REFL_CONSEQ_CONV
fun hchange_core_cc lemma_th cont_ecc1 cont_ecc2 dir t = let
val _ = cfHeapsBaseLib.dest_sep_imp t
val cc =
hpull_conseq_conv THEN_DCC
DEPTH_CONSEQ_CONV (hchange_apply_cc lemma_th cont_ecc1 cont_ecc2)
in cc dir t end
fun hchange_conseq_conv th =
hchange_core_cc th hcancel_cont_ecc id_cont_ecc
fun hchanges_conseq_conv th =
hchange_core_cc th hcancel_cont_ecc hsimpl_cont_ecc
fun hchange_top th = CONSEQ_CONV_TAC (hchange_conseq_conv th)
fun hchanges_top th = CONSEQ_CONV_TAC (hchanges_conseq_conv th)
fun hchange th = DEPTH_CONSEQ_CONV_TAC (hchange_conseq_conv th)
fun hchanges th = DEPTH_CONSEQ_CONV_TAC (hchanges_conseq_conv th)
end