1 2open HolKernel boolLib bossLib Parse; 3open pred_setTheory arithmeticTheory pairTheory listTheory combinTheory finite_mapTheory; 4 5 6val _ = new_theory "cheney_gc"; 7val _ = ParseExtras.temp_loose_equality() 8infix \\ 9val op \\ = op THEN; 10val RW = REWRITE_RULE; 11val RW1 = ONCE_REWRITE_RULE; 12 13 14(* -- helper -- *) 15 16fun FORCE_PBETA_CONV tm = let 17 val (tm1,tm2) = dest_comb tm 18 val vs = fst (pairSyntax.dest_pabs tm1) 19 fun expand_pair_conv tm = ISPEC tm (GSYM pairTheory.PAIR) 20 fun get_conv vs = let 21 val (x,y) = pairSyntax.dest_pair vs 22 in expand_pair_conv THENC (RAND_CONV (get_conv y)) end 23 handle HOL_ERR e => ALL_CONV 24 in (RAND_CONV (get_conv vs) THENC PairRules.PBETA_CONV) tm end; 25 26(* -- abstraction -- *) 27 28val SUBSET0_DEF = new_infixr_definition 29 ("SUBSET0_DEF", ���SUBSET0 s t = s SUBSET (0 INSERT t)���,451); 30 31val SUBSET0_TRANS = store_thm("SUBSET0_TRANS", 32 ``!x y z. x SUBSET0 y /\ y SUBSET0 z ==> x SUBSET0 z``, 33 REWRITE_TAC [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] \\ METIS_TAC []); 34 35val _ = Hol_datatype ` 36 heap_type = EMP | REF of num | DATA of num # num # 'a`; 37 38val isREF_def = Define `isREF x = ?i. x = REF i`; 39val getREF_def = Define `getREF (REF x) = x`; 40val getDATA_def = Define `getDATA (DATA y) = y`; 41 42val heap_type_distinct = fetch "-" "heap_type_distinct" 43val heap_type_11 = fetch "-" "heap_type_11" 44 45val RANGE_def = Define `RANGE(i:num,j) k = i <= k /\ k < j`; 46val IRANGE_def = Define `IRANGE(i:num,j) k = ~(i <= k /\ k < j)`; 47 48val CUT_def = Define `CUT (i,j) m = \k. if RANGE (i,j) k then m k else EMP`; 49val ICUT_def = Define `ICUT (i,j) m = \k. if IRANGE (i,j) k then m k else EMP`; 50 51val D0 = Define `D0 m k = ?x y z. m (k:num) = DATA(x,y,z)`; 52val D1 = Define `D1 m x = ?k y z. (m (k:num) = DATA(x,y,z)) \/ (m k = DATA(y,x,z))`; 53val R0 = Define `R0 m k = ?a. m (k:num) = REF a`; 54val R1 = Define `R1 m a = ?k. m (k:num) = REF a`; 55val DR0 = Define `DR0 m k = D0 m k \/ R0 m k` 56val DR1 = Define `DR1 m k = D1 m k \/ R1 m k` 57 58val ADDR_def = Define ` 59 (ADDR k n EMP = (n = k)) /\ 60 (ADDR k n (REF i) = (n = i)) /\ 61 (ADDR k n (DATA x) = (n = k))`; 62 63val abs_def = Define ` 64 abs m (a,n,n',d) = 65 ?k k'. (m a = DATA(k,k',d)) /\ ADDR k n (m k) /\ ADDR k' n' (m k')`; 66 67val basic_abs = Define ` 68 basic_abs m (a,n,n',d) = (m a = DATA(n,n',d))`; 69 70val apply_def = Define `apply h s (a,n,n',d) = (h a,h n,h n',d) IN s`; 71 72val PATH_def = Define ` 73 (PATH (x,[]) s = T) /\ 74 (PATH (x,y::ys) s = PATH (y,ys) s /\ ?z d. (x,y,z,d) IN s \/ (x,z,y,d) IN s)`; 75 76val reachable_def = Define ` 77 reachable r s i = (r = i) \/ ?p. PATH (r,p++[i]) s`; 78 79val UPDATE_thm = prove( 80 ``!a b. a =+ b = (\f k. (if k = a then b else f k))``, 81 SIMP_TAC std_ss [UPDATE_def,FUN_EQ_THM] \\ METIS_TAC []); 82 83val roots_inv_def = Define ` 84 roots_inv (b,j,m,xx) = 85 ?v. (v o v = I) /\ (xx = apply v (abs m)) /\ 86 (!k. ~isREF(m k) /\ ~RANGE(b,j)k ==> (v k = k)) /\ 87 (!k i. (m k = REF i) ==> (v k = i))`; 88 89val cheney_inv_def = Define ` 90 cheney_inv(b,b',i,j,j',e,f,m,x,xx,r) = 91 (0 < b /\ b <= b' /\ b' <= j /\ b <= i /\ i <= j /\ j <= e /\ e <= f) /\ 92 (!k. j <= k /\ k < e \/ f < k ==> (m k = EMP)) /\ (* all EMP between j and e *) 93 (D0(CUT(b,j)m) = RANGE(b,j)) /\ (* all DATA between b and j *) 94 (D1(CUT(b,i)m) SUBSET0 RANGE(b,j)) /\ (* b-i links only to b-j and nil *) 95 (RANGE(i,j') SUBSET (r UNION D1(CUT(b,i)m))) /\ (* every i-j is linked to by some b-i *) 96 (D1(CUT(i,j)m) SUBSET0 DR0(ICUT(b,e)m)) /\ (* i-j links only outside of b-e *) 97 (D1(ICUT(b,e)m) SUBSET0 DR0(ICUT(b,e)m)) /\ (* outside of b-e links only to outside b-e *) 98 (R1(m) = RANGE(b,j)) /\ (* all REFs refer to b-j elements *) 99 (!i j k. (m i = REF k) /\ (m j = REF k) ==> (i = j)) /\ (* REFs are injective *) 100 (CARD(D0(ICUT(b,e)m)) <= e-j) /\ (* num of elements outside b-e fit into e-j *) 101 FINITE (D0(ICUT(b,e)m)) /\ (* the set is finite *) 102 (m 0 = EMP) /\ (* 0 points at no data *) 103 RANGE(b,i) SUBSET (* all of b-i is reachable from r *) 104 (\x. ?t. t IN r /\ x IN reachable t (basic_abs(CUT(b,i)m))) /\ 105 (!k i. (x k = REF i) ==> (m k = REF i)) /\ (* refernces are reserved *) 106 roots_inv (b,j,m,abs xx) (* memory is permuted *)`; 107 108val ok_state_def = Define ` 109 ok_state (i,e,r,l,u,m) = 110 let a = (if u then 1 + l else 1) in 111 let s = RANGE(a,i) in 112 a <= i /\ i <= e /\ (e = a + l) /\ 113 (!k. MEM k r /\ ~(k = 0) ==> k IN s) /\ 114 (!k. ~(k IN s) ==> (m k = EMP)) /\ 115 (!k. k IN s ==> ?x y d. (m k = DATA(x,y,d)) /\ {x;y} SUBSET0 s)`; 116 117val move_def = Define ` 118 move(x,j,m) = 119 if x = 0 then (x,j,m) else 120 if isREF (m x) then (getREF (m x),j,m) else 121 let m = (j =+ m x) m in 122 let m = (x =+ REF j) m in 123 (j,j+1,m)`; 124 125val cheney_step_def = Define ` 126 cheney_step (i,j,e,m) = 127 let (x,y,d) = getDATA (m i) in 128 let (x,j,m) = move (x,j,m) in 129 let (y,j,m) = move (y,j,m) in 130 let m = (i =+ DATA (x,y,d)) m in 131 (i+1,j,e,m)`; 132 133val cheney_def = tDefine "cheney" ` 134 cheney(i,j,e,m) = 135 if (i = j) \/ e < i then (i,m) else 136 cheney(cheney_step(i,j,e,m))` 137 (WF_REL_TAC `measure (\(i,j,e,m). (e + 1) - i)` 138 \\ REWRITE_TAC [cheney_step_def,LET_DEF] 139 \\ CONV_TAC (DEPTH_CONV FORCE_PBETA_CONV) 140 \\ REWRITE_TAC [FST,SND] \\ DECIDE_TAC); 141 142val cheney_ind = fetch "-" "cheney_ind"; 143 144val m_DATA = store_thm("m_DATA", 145 ``cheney_inv(b,b',i,j,j',e,f,m,x,xx,r) /\ ~(i = j) ==> ?ax ay ad. m i = DATA (ax,ay,ad)``, 146 SIMP_TAC std_ss [cheney_inv_def,FUN_EQ_THM,D0,IN_DEF,RANGE_def,CUT_def] 147 \\ REPEAT STRIP_TAC \\ `b <= i /\ i < j` by DECIDE_TAC \\ METIS_TAC []); 148 149val IN_EQ_SUBSET = 150 GEN_ALL (GSYM (REWRITE_CONV [INSERT_SUBSET,EMPTY_SUBSET] ``{i:'a} SUBSET x``)); 151 152val RANGE_IRANGE = prove( 153 ``!b e x y. RANGE (b,e) x /\ IRANGE (b,e) y ==> ~(x = y)``, 154 REWRITE_TAC [RANGE_def,IRANGE_def] \\ DECIDE_TAC); 155 156val RANGE_expand = prove( 157 ``!i j k x. RANGE (i,j) x /\ j <= k ==> RANGE (i,k) x``, 158 REWRITE_TAC [RANGE_def,IRANGE_def] \\ DECIDE_TAC); 159 160val RANGE_expand_left = prove( 161 ``!i j k x. RANGE (i,j) x /\ k <= i ==> RANGE (k,j) x``, 162 REWRITE_TAC [RANGE_def,IRANGE_def] \\ DECIDE_TAC); 163 164val CUT_update = prove( 165 ``~RANGE (i,j) k ==> (CUT (i,j) ((k =+ x) m) = CUT (i,j) m)``, 166 SIMP_TAC std_ss [CUT_def,UPDATE_def,FUN_EQ_THM] \\ METIS_TAC []); 167 168val ICUT_update = prove( 169 ``~IRANGE (i,j) k ==> (ICUT (i,j) ((k =+ x) m) = ICUT (i,j) m)``, 170 SIMP_TAC std_ss [ICUT_def,UPDATE_def,FUN_EQ_THM] \\ METIS_TAC []); 171 172val update_update = prove( 173 ``!m i x y. (i =+ y) ((i =+ x) m) = (i=+ y) m``, 174 SIMP_TAC std_ss [FUN_EQ_THM,UPDATE_def]); 175 176val expand_CUT = prove( 177 ``RANGE (a,b) SUBSET RANGE (c,d) /\ (CUT(c,d)m=CUT(c,d)n) ==> (CUT(a,b)m=CUT(a,b)n)``, 178 SIMP_TAC std_ss [SUBSET_DEF,IN_DEF,FUN_EQ_THM,RANGE_def,CUT_def] \\ METIS_TAC []); 179 180val D1_SUBSET0 = prove( 181 ``D1 (CUT(j,j+1)m) SUBSET0 s /\ D1 (CUT(i,j)m) SUBSET0 s ==> 182 D1 (CUT(i,j+1)m) SUBSET0 s``, 183 REWRITE_TAC [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 184 \\ SIMP_TAC std_ss [IN_DEF,D1,CUT_def,RANGE_def,DECIDE ``k<n+1=k<=n``] 185 \\ METIS_TAC [DECIDE ``n <= k \/ k < n:num``,fetch "-" "heap_type_distinct"]); 186 187val swap_def = Define ` 188 swap i j = \k. if k = i then j else if k = j then i else k`; 189 190val swap_swap = store_thm("swap_swap", 191 ``!i:'a j. swap i j o swap i j = I``, 192 SIMP_TAC std_ss [swap_def,FUN_EQ_THM] 193 \\ REPEAT STRIP_TAC \\ Cases_on `x = i` \\ Cases_on `x = j` \\ Cases_on `i = j` 194 \\ ASM_SIMP_TAC std_ss []); 195 196val swap_swap2 = prove( 197 ``!i:'a j x. swap i j (swap i j x) = x``, 198 SIMP_TAC std_ss [swap_def] 199 \\ REPEAT STRIP_TAC \\ Cases_on `x = i` \\ Cases_on `x = j` \\ Cases_on `i = j` 200 \\ ASM_SIMP_TAC std_ss []); 201 202val swap_id = prove( 203 ``!i j k. ~(i = k) /\ ~(j = k) ==> (swap i j k = k)``, 204 SIMP_TAC std_ss [swap_def]); 205 206val apply_apply = store_thm("apply_apply", 207 ``!s f g. apply f (apply g s) = apply (g o f) s``, 208 SIMP_TAC std_ss [FUN_EQ_THM] \\ REPEAT STRIP_TAC 209 \\ Cases_on `x` \\ Cases_on `r` \\ Cases_on `r'` 210 \\ SIMP_TAC std_ss [apply_def,IN_DEF]); 211 212val apply_I = store_thm("apply_I", 213 ``!s. apply I s = s``, 214 REWRITE_TAC [FUN_EQ_THM] \\ REPEAT STRIP_TAC 215 \\ Cases_on `x` \\ Cases_on `r` \\ Cases_on `r'` \\ SIMP_TAC std_ss [apply_def,IN_DEF]); 216 217val RANGE_IMP_NOT_DR0 = prove( 218 ``!i j x m. RANGE (i,j) x ==> ~DR0 (ICUT(i,j)m) x``, 219 SIMP_TAC std_ss [DR0,D0,R0,ICUT_def,IRANGE_def,RANGE_def,heap_type_distinct]); 220 221val D0_IMP = prove( 222 ``D0 (CUT (b,j) m) i ==> ?h g dd. RANGE(b,j)i /\ (m i = DATA(h,g,dd))``, 223 SIMP_TAC std_ss [D0,CUT_def] \\ METIS_TAC [heap_type_distinct]); 224 225val D1_IMP = prove( 226 ``D1 (CUT (b,i) m) j ==> 227 ?h g dd. RANGE(b,i)h /\ (~(m h = DATA(j,g,dd)) ==> (m h = DATA(g,j,dd)))``, 228 SIMP_TAC std_ss [D1,CUT_def] \\ REPEAT STRIP_TAC 229 \\ Q.EXISTS_TAC `k` \\ Cases_on `RANGE (b,i) k` 230 \\ FULL_SIMP_TAC std_ss [heap_type_distinct,heap_type_11] \\ METIS_TAC []); 231 232val lemma2 = prove( 233 ``k IN D1 m /\ ~(j = x) /\ IRANGE(b,e)x /\ ~(j = e) /\ 234 cheney_inv (b,b',i,j,j',e,f,m,w,xx,r) /\ (m x = DATA (n',n'',d')) /\ (m j = EMP) ==> 235 (ADDR k (swap j x t) (((x =+ REF j) ((j =+ (DATA (n',n'',d'))) m)) k) = 236 ADDR k t (m k))``, 237 SIMP_TAC std_ss [UPDATE_def,swap_def] \\ Cases_on `k = j` \\ ASM_REWRITE_TAC [] THENL [ 238 REPEAT STRIP_TAC 239 \\ `{j} SUBSET D1 m` by METIS_TAC [IN_EQ_SUBSET] \\ FULL_SIMP_TAC std_ss [cheney_inv_def] 240 \\ `{j} SUBSET (D1 (ICUT (b,e) m)) \/ {j} SUBSET (D1 (CUT (b,i) m)) \/ 241 {j} SUBSET (D1 (CUT (i,j) m)) \/ {j} SUBSET (D1 (CUT (j,e) m))` by 242 (FULL_SIMP_TAC std_ss [GSYM IN_EQ_SUBSET,IN_DEF,D1,GSYM RANGE_def] 243 \\ SIMP_TAC std_ss [CUT_def,ICUT_def] 244 \\ `IRANGE(b,e)k' \/ RANGE(b,i)k' \/ RANGE(i,j)k' \/ RANGE(j,e)k'` by 245 (REWRITE_TAC [RANGE_def,IRANGE_def] \\ DECIDE_TAC) 246 \\ METIS_TAC [heap_type_distinct]) 247 THENL [ 248 FULL_SIMP_TAC bool_ss [SUBSET0_DEF] 249 \\ `{j} SUBSET 0 INSERT DR0 (ICUT (b,e) m)` by METIS_TAC [SUBSET_TRANS] 250 \\ FULL_SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_INSERT,IN_DEF] THEN1 `F` by DECIDE_TAC 251 \\ `RANGE (b,e) j` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 252 \\ IMP_RES_TAC RANGE_IMP_NOT_DR0, 253 FULL_SIMP_TAC bool_ss [SUBSET0_DEF] 254 \\ `{j} SUBSET 0 INSERT RANGE (b,j)` by METIS_TAC [SUBSET_TRANS] 255 \\ FULL_SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_INSERT,IN_DEF,RANGE_def] 256 \\ `F` by DECIDE_TAC, 257 FULL_SIMP_TAC bool_ss [SUBSET0_DEF] 258 \\ `{j} SUBSET 0 INSERT DR0 (ICUT (b,e) m)` by METIS_TAC [SUBSET_TRANS] 259 \\ FULL_SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_INSERT,IN_DEF] THEN1 `F` by DECIDE_TAC 260 \\ `RANGE (b,e) j` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 261 \\ IMP_RES_TAC RANGE_IMP_NOT_DR0, 262 FULL_SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_INSERT,IN_DEF,D1,CUT_def,RANGE_def] 263 \\ `F` by METIS_TAC [heap_type_distinct]], 264 Cases_on `k = x` \\ ASM_SIMP_TAC std_ss [ADDR_def] THEN1 METIS_TAC [] 265 \\ Cases_on `m k` \\ ASM_REWRITE_TAC [ADDR_def] THENL [ 266 Cases_on `t = j` \\ Cases_on `t = x` \\ FULL_SIMP_TAC bool_ss [], 267 REPEAT STRIP_TAC 268 \\ `~(n = x)` by 269 (CCONTR_TAC \\ FULL_SIMP_TAC bool_ss [] 270 \\ `{x} SUBSET R1 m` by (SIMP_TAC std_ss [GSYM IN_EQ_SUBSET,IN_DEF] \\ METIS_TAC [R1]) 271 \\ `{x} SUBSET RANGE (b,j)` by METIS_TAC [cheney_inv_def,SUBSET_TRANS] 272 \\ FULL_SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_DEF,RANGE_def,IRANGE_def,cheney_inv_def] 273 \\ DECIDE_TAC) 274 \\ `~(n = j)` by 275 (CCONTR_TAC \\ FULL_SIMP_TAC bool_ss [] 276 \\ `{j} SUBSET R1 m` by (SIMP_TAC std_ss [GSYM IN_EQ_SUBSET,IN_DEF] \\ METIS_TAC [R1]) 277 \\ `{j} SUBSET RANGE (b,j)` by METIS_TAC [cheney_inv_def,SUBSET_TRANS] 278 \\ FULL_SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_DEF,RANGE_def,IRANGE_def,cheney_inv_def] 279 \\ DECIDE_TAC) 280 \\ METIS_TAC [], 281 Cases_on `t = j` \\ Cases_on `t = x` \\ FULL_SIMP_TAC bool_ss []]]); 282 283val lemma = prove( 284 ``(m x = DATA (n',n'',d')) /\ (m j = EMP) ==> 285 (((x =+ REF j) ((j =+ DATA (n',n'',d')) m) (swap j x a) = DATA (k,k',v)) = 286 (m a = DATA (k,k',v)))``, 287 SIMP_TAC std_ss [UPDATE_def,swap_def] 288 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC 289 \\ Cases_on `a = j` \\ FULL_SIMP_TAC bool_ss [swap_def,heap_type_distinct] 290 \\ Cases_on `a = x` \\ FULL_SIMP_TAC bool_ss [swap_def,heap_type_11,PAIR_EQ]); 291 292val move_lemma_lemma = prove( 293 ``!d' b b' i j j' e m w r x n' n''. 294 (m x = DATA (n',n'',d')) /\ (m j = EMP) /\ ~(j = e) /\ 295 cheney_inv (b,b',i,j,j',e,f,m,w,xx,r) /\ IRANGE (b,e) x /\ ~(x = 0) ==> 296 (apply (swap j x) (abs((x =+ REF j) ((j =+ m x) m))) = abs m)``, 297 REWRITE_TAC [FUN_EQ_THM] \\ REPEAT STRIP_TAC 298 \\ `?a t u v. x' = (a,t,u,v)` by METIS_TAC [PAIR_EQ,PAIR] 299 \\ ASM_SIMP_TAC std_ss [apply_def,IN_DEF,abs_def,lemma] 300 \\ `~(j = x)` by (FULL_SIMP_TAC bool_ss [IRANGE_def,cheney_inv_def] \\ DECIDE_TAC) 301 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC 302 \\ Q.EXISTS_TAC `k` \\ Q.EXISTS_TAC `k'` 303 \\ `k IN D1 m /\ k' IN D1 m` by (SIMP_TAC std_ss [IN_DEF,D1] \\ METIS_TAC []) 304 \\ ASSUME_TAC (GSYM (UNDISCH_ALL (RW [GSYM AND_IMP_INTRO] (Q.INST [`d`|->`v`] lemma2)))) 305 \\ ASSUME_TAC (GSYM (UNDISCH_ALL (RW [GSYM AND_IMP_INTRO] 306 (Q.INST [`d`|->`v`,`k`|->`k'`,`t`|->`u`] lemma2)))) 307 \\ ASM_REWRITE_TAC [] \\ METIS_TAC []); 308 309val move_lemma2 = prove( 310 ``!i j s t. (apply (swap i j) s = t) = (s = apply (swap i j) t)``, 311 REWRITE_TAC [apply_def,swap_def,FUN_EQ_THM] 312 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC 313 \\ Cases_on `x` \\ Cases_on `r` \\ Cases_on `r'` 314 \\ POP_ASSUM (ASSUME_TAC o 315 Q.SPECL [`(swap i j q,swap i j q',swap i j q'',r)`]) 316 \\ FULL_SIMP_TAC std_ss [apply_def,swap_def,IN_DEF] 317 \\ Cases_on `q= i` \\ FULL_SIMP_TAC bool_ss [] 318 \\ Cases_on `q'= i` \\ FULL_SIMP_TAC bool_ss [] 319 \\ Cases_on `q''= i` \\ FULL_SIMP_TAC bool_ss [] 320 \\ Cases_on `q= j` \\ FULL_SIMP_TAC bool_ss [] 321 \\ Cases_on `q'= j` \\ FULL_SIMP_TAC bool_ss [] 322 \\ Cases_on `q''= j` \\ FULL_SIMP_TAC bool_ss []); 323 324val cheney_inv_CUT_lemma = prove( 325 ``cheney_inv (b,b',i,j,j3,e,f,m,w,xx,r) /\ ~(j = e) /\ IRANGE(b,e)x ==> 326 (RANGE (b,i) SUBSET RANGE (b,j)) /\ ~RANGE(b,j+1)x /\ ~RANGE(b,i)j /\ ~RANGE(b,i)x /\ 327 (RANGE (b,j+1) SUBSET RANGE (b,e)) /\ RANGE (b,j) SUBSET0 RANGE (b,j + 1) /\ 328 (RANGE (i,j+1) SUBSET RANGE (b,j+1)) /\ ~RANGE(i,j+1)x /\ ~RANGE(b,b')j /\ ~RANGE(b,b')x /\ 329 ~RANGE(i,j)j /\ ~RANGE(b,e)x /\ ~RANGE(b,j)j /\ ~RANGE(b,j)x``, 330 FULL_SIMP_TAC bool_ss [SUBSET_DEF,SUBSET0_DEF,IN_INSERT] 331 \\ FULL_SIMP_TAC std_ss [IN_DEF,cheney_inv_def,RANGE_def,IRANGE_def] 332 \\ REPEAT STRIP_TAC \\ DECIDE_TAC); 333 334val RANGE_simp = prove( 335 ``!i j k. ~(i = j) ==> (RANGE(k,i+1)j = RANGE(k,i)j)``, 336 SIMP_TAC bool_ss [RANGE_def,IN_DEF] \\ DECIDE_TAC); 337 338val move_lemma = store_thm("move_lemma", 339 ``cheney_inv (b,b',i,j,j3,e,f,m,w,xx,r) /\ {x} SUBSET0 DR0(ICUT(b,e)m) ==> 340 (move(x,j,m) = (x2,j2,m2)) ==> 341 cheney_inv(b,b',i,j2,j3,e,f,m2,w,xx,r) /\ {x2} SUBSET0 RANGE(b,j2) /\ j <= j2 /\ 342 (CUT(b,j)m = CUT(b,j)m2) /\ (DR0 (ICUT(b,e)m) = DR0 (ICUT(b,e)m2)) /\ 343 (if x = 0 then x2 = 0 else (m2 x = REF x2) /\ D0 (CUT(b,j2)m2) x2) /\ 344 (!a i. (m a = REF i) ==> (m2 a = REF i)) /\ 345 (if ~(x = 0) /\ (m2 x = REF j) then j2 = j + 1 else j2 = j) /\ 346 (~(x = 0) /\ ~isREF (m x) ==> (abs m = apply (swap j x) (abs m2))) /\ x <= f``, 347 Cases_on `x = 0` \\ ASM_SIMP_TAC bool_ss [move_def,PAIR_EQ,LESS_EQ_REFL] 348 \\ ASM_SIMP_TAC bool_ss [SUBSET0_DEF,INSERT_SUBSET,EMPTY_SUBSET,IN_INSERT] 349 THEN1 (ONCE_REWRITE_TAC [EQ_SYM_EQ] \\ SIMP_TAC bool_ss [ZERO_LESS_EQ]) \\ STRIP_TAC 350 \\ `x <= f` by 351 (Cases_on `IRANGE (b,e) x` \\ FULL_SIMP_TAC bool_ss [IN_DEF,DR0,D0,R0, 352 ICUT_def,heap_type_distinct,cheney_inv_def,DECIDE ``x < j = ~(j <= x:num)``] 353 \\ METIS_TAC [heap_type_distinct]) \\ ASM_SIMP_TAC bool_ss [] 354 \\ Cases_on `isREF (m x)` \\ ASM_REWRITE_TAC [] 355 THEN1 356 (FULL_SIMP_TAC bool_ss [isREF_def,getREF_def,PAIR_EQ] 357 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ,SUBSET_REFL,LESS_EQ_REFL] 358 \\ ASM_SIMP_TAC bool_ss [] \\ REPEAT STRIP_TAC 359 \\ FULL_SIMP_TAC bool_ss [cheney_inv_def,heap_type_11] THENL [ 360 Q.PAT_X_ASSUM `R1 m = RANGE (b,j)` (fn th => REWRITE_TAC [GSYM th]) \\ DISJ2_TAC 361 \\ SIMP_TAC bool_ss [GSYM IN_EQ_SUBSET,IN_DEF,R1] \\ METIS_TAC [], 362 FULL_SIMP_TAC bool_ss [cheney_inv_def,SUBSET_DEF,IN_DEF] 363 \\ `R1 m i'` by (REWRITE_TAC [R1] \\ METIS_TAC []) \\ METIS_TAC [], 364 FULL_SIMP_TAC bool_ss [cheney_inv_def,SUBSET_DEF,IN_DEF] 365 \\ `~RANGE (b,i') i'` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 366 \\ `R1 m i'` by (REWRITE_TAC [R1] \\ METIS_TAC []) \\ METIS_TAC []]) 367 \\ SIMP_TAC std_ss [LET_DEF] 368 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ] \\ ASM_SIMP_TAC bool_ss [] \\ STRIP_TAC 369 \\ `IRANGE (b,e) x /\ ?t u v. m x = DATA (t,u,v)` by 370 (FULL_SIMP_TAC bool_ss [IN_DEF,DR0,isREF_def,D0,R0,ICUT_def] 371 \\ Cases_on `IRANGE (b,e) x` 372 \\ FULL_SIMP_TAC bool_ss [heap_type_distinct] \\ METIS_TAC []) 373 \\ `~(j = e)` by 374 (CCONTR_TAC \\ FULL_SIMP_TAC bool_ss [DECIDE ``m <= n - n = (m = 0)``,cheney_inv_def] 375 \\ `x IN D0 (ICUT(b,e)m)` 376 by (FULL_SIMP_TAC bool_ss [IN_DEF,D0,ICUT_def] \\ METIS_TAC[]) 377 \\ METIS_TAC [CARD_EQ_0,NOT_IN_EMPTY]) 378 \\ `ICUT(b,e) ((x =+ (REF j)) ((j =+ m x) m)) = 379 ICUT(b,e) ((x =+ (REF j)) m)` by 380 (Cases_on `x = j` \\ ASM_REWRITE_TAC [update_update] 381 \\ SIMP_TAC std_ss [ICUT_def,FUN_EQ_THM,UPDATE_def] \\ STRIP_TAC 382 \\ Cases_on `IRANGE (b,e) x'` \\ ASM_REWRITE_TAC [] 383 \\ Cases_on `x = x'` \\ ASM_REWRITE_TAC [] 384 \\ `~(j = x')` by (FULL_SIMP_TAC bool_ss [cheney_inv_def,IRANGE_def] \\ DECIDE_TAC) 385 \\ ASM_REWRITE_TAC []) 386 \\ `abs ((x =+ REF j) ((j =+ DATA (t,u,v)) m)) = apply (swap j x) (abs m)` by 387 (Q.PAT_X_ASSUM `m x = DATA (t,u,v)` (fn th => REWRITE_TAC [GSYM th] \\ ASSUME_TAC th) 388 \\ REWRITE_TAC [GSYM move_lemma2] 389 \\ MATCH_MP_TAC (GEN_ALL move_lemma_lemma) 390 \\ Q.EXISTS_TAC `xx` \\ Q.EXISTS_TAC `f` \\ Q.EXISTS_TAC `v` 391 \\ Q.EXISTS_TAC `b` \\ Q.EXISTS_TAC `b'` \\ Q.EXISTS_TAC `i` 392 \\ Q.EXISTS_TAC `j3` \\ Q.EXISTS_TAC `e` \\ Q.EXISTS_TAC `w` 393 \\ Q.EXISTS_TAC `r` \\ Q.EXISTS_TAC `t` \\ Q.EXISTS_TAC `u` 394 \\ FULL_SIMP_TAC std_ss [cheney_inv_def] 395 \\ `j <= j /\ j < e` by DECIDE_TAC 396 \\ METIS_TAC []) 397 \\ IMP_RES_TAC cheney_inv_CUT_lemma 398 \\ REPEAT (Q.PAT_X_ASSUM `!tyu.fgh` (fn th => ALL_TAC)) 399 \\ FULL_SIMP_TAC std_ss [cheney_inv_def] 400 \\ ASM_SIMP_TAC bool_ss [CUT_update,apply_apply,swap_swap,apply_I] 401 \\ REPEAT STRIP_TAC THEN1 DECIDE_TAC THEN1 DECIDE_TAC THEN1 DECIDE_TAC 402 THEN1 403 (`~(k = j) /\ ~(k = x)` by (FULL_SIMP_TAC bool_ss [IRANGE_def] \\ DECIDE_TAC) 404 \\ ASM_SIMP_TAC bool_ss [UPDATE_def] \\ METIS_TAC [DECIDE ``j + 1 <= k ==> j <= k``]) 405 THEN1 406 (`~(k = j) /\ ~(x = k)` by DECIDE_TAC \\ ASM_SIMP_TAC bool_ss [UPDATE_def]) 407 THEN1 408 (ASM_SIMP_TAC std_ss [FUN_EQ_THM,D0,CUT_def,RANGE_def,IN_DEF] 409 \\ STRIP_TAC \\ Cases_on `x' = j` \\ ASM_REWRITE_TAC [] 410 \\ ASM_SIMP_TAC std_ss [UPDATE_def] THEN1 METIS_TAC [heap_type_distinct] 411 \\ ASM_SIMP_TAC bool_ss [DECIDE ``~(x = n) ==> (x < n + 1 = x < n)``] 412 \\ REWRITE_TAC [GSYM RANGE_def] 413 \\ Cases_on ` RANGE (b,j) x'` \\ ASM_REWRITE_TAC [heap_type_distinct] 414 \\ FULL_SIMP_TAC bool_ss [D0,FUN_EQ_THM,CUT_def] \\ METIS_TAC []) 415 THEN1 416 (MATCH_MP_TAC SUBSET0_TRANS \\ Q.EXISTS_TAC `RANGE (b,j)` \\ ASM_REWRITE_TAC []) 417 THEN1 418 (Q.PAT_X_ASSUM `m x = DATA (t,u,v)` (ASSUME_TAC o GSYM) \\ ASM_REWRITE_TAC [] 419 \\ MATCH_MP_TAC SUBSET0_TRANS \\ Q.EXISTS_TAC `DR0 (ICUT (b,e) m)` 420 \\ ONCE_REWRITE_TAC [CONJ_COMM] \\ STRIP_TAC THEN1 421 (REWRITE_TAC [DR0,SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 422 \\ SIMP_TAC std_ss [IN_DEF,DR0,UPDATE_def,ICUT_def,FUN_EQ_THM,D0,R0] 423 \\ STRIP_TAC \\ Cases_on `IRANGE (b,e) x'` 424 \\ ASM_REWRITE_TAC [heap_type_distinct] \\ METIS_TAC []) 425 \\ MATCH_MP_TAC D1_SUBSET0 \\ ASM_SIMP_TAC bool_ss [CUT_update] 426 \\ Q.PAT_X_ASSUM `DATA (t,u,v) = m x` (ASSUME_TAC o GSYM) \\ ASM_REWRITE_TAC [] 427 \\ MATCH_MP_TAC SUBSET0_TRANS \\ Q.EXISTS_TAC `{t;u}` \\ STRIP_TAC THEN1 428 (REWRITE_TAC [DR0,SUBSET0_DEF,SUBSET_DEF,IN_INSERT,CUT_def] 429 \\ SIMP_TAC std_ss [IN_DEF,DR0,UPDATE_def,ICUT_def,FUN_EQ_THM,D0,R0] 430 \\ SIMP_TAC std_ss [RANGE_def,DECIDE ``j <= k /\ k < j+1 = (j = k)``,D1] 431 \\ REPEAT (POP_ASSUM (fn th => ALL_TAC)) 432 \\ REPEAT STRIP_TAC \\ Cases_on `j = k` 433 \\ FULL_SIMP_TAC bool_ss [heap_type_11,PAIR_EQ,heap_type_distinct]) 434 \\ MATCH_MP_TAC SUBSET0_TRANS \\ Q.EXISTS_TAC `D1 (ICUT (b,e) m)` \\ STRIP_TAC THEN1 435 (REWRITE_TAC [SUBSET0_DEF,INSERT_SUBSET,EMPTY_SUBSET,IN_INSERT] 436 \\ MATCH_MP_TAC (METIS_PROVE [] ``x /\ y ==> (t \/ x) /\ (d:bool \/ y)``) 437 \\ SIMP_TAC std_ss [IN_DEF,D1,ICUT_def] \\ METIS_TAC []) 438 \\ ASM_REWRITE_TAC []) 439 THEN1 440 (MATCH_MP_TAC SUBSET0_TRANS \\ Q.EXISTS_TAC `D1 (ICUT (b,e) m)` \\ STRIP_TAC THEN1 441 (REWRITE_TAC [DR0,SUBSET0_DEF,SUBSET_DEF,IN_INSERT,CUT_def,D1] 442 \\ SIMP_TAC std_ss [IN_DEF,DR0,UPDATE_def,ICUT_def,FUN_EQ_THM,D0,R0,D1] 443 \\ METIS_TAC [heap_type_11,PAIR_EQ,heap_type_distinct]) 444 \\ MATCH_MP_TAC SUBSET0_TRANS 445 \\ Q.EXISTS_TAC `DR0 (ICUT (b,e) m)` \\ ASM_REWRITE_TAC [] 446 \\ REWRITE_TAC [DR0,SUBSET0_DEF,SUBSET_DEF,IN_INSERT,CUT_def,D1] 447 \\ SIMP_TAC std_ss [IN_DEF,DR0,UPDATE_def,ICUT_def,FUN_EQ_THM,D0,R0] 448 \\ METIS_TAC [heap_type_11,PAIR_EQ,heap_type_distinct]) 449 THEN1 450 (`j < e` by DECIDE_TAC 451 \\ `m j = EMP` by METIS_TAC [LESS_EQ_REFL] 452 \\ sg `!xx. R1 ((x =+ REF j) ((j =+ DATA (t,u,v)) m)) xx = (j = xx) \/ R1 m xx` 453 THENL [ALL_TAC,ASM_SIMP_TAC bool_ss [FUN_EQ_THM,RANGE_def] \\ DECIDE_TAC] 454 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC 455 \\ FULL_SIMP_TAC bool_ss [R1,UPDATE_def] THENL [ 456 Cases_on `x = k` \\ FULL_SIMP_TAC bool_ss [heap_type_11] 457 \\ Cases_on `j = k` \\ FULL_SIMP_TAC bool_ss [heap_type_distinct] \\ METIS_TAC [], 458 Q.EXISTS_TAC `x` \\ METIS_TAC [], 459 Q.EXISTS_TAC `k` \\ Cases_on `k = x` \\ FULL_SIMP_TAC std_ss [heap_type_distinct] 460 \\ Cases_on `j = k` \\ FULL_SIMP_TAC std_ss [heap_type_distinct]]) 461 THEN1 462 (Cases_on `k = j` THENL [ 463 Cases_on `i' = x` THENL [ALL_TAC, 464 Cases_on `j = i'` \\ FULL_SIMP_TAC bool_ss [UPDATE_def,heap_type_distinct] 465 \\ FULL_SIMP_TAC bool_ss [FUN_EQ_THM,R1] \\ METIS_TAC []] 466 \\ Cases_on `j' = x` THENL [ALL_TAC, 467 Cases_on `j = j'` \\ FULL_SIMP_TAC bool_ss [UPDATE_def,heap_type_distinct] 468 \\ FULL_SIMP_TAC bool_ss [FUN_EQ_THM,R1] \\ METIS_TAC []] 469 \\ ASM_SIMP_TAC bool_ss [], 470 `m i' = REF k` by 471 (Cases_on `x = i'` \\ Cases_on `j = i'` 472 \\ FULL_SIMP_TAC bool_ss [UPDATE_def,heap_type_distinct,heap_type_11] \\ METIS_TAC []) 473 \\ `m j' = REF k` by 474 (Cases_on `x = j'` \\ Cases_on `j = j'` 475 \\ FULL_SIMP_TAC bool_ss [UPDATE_def,heap_type_distinct,heap_type_11] \\ METIS_TAC []) 476 \\ METIS_TAC []]) 477 THEN1 478 (REWRITE_TAC [SUB_PLUS] 479 \\ `D0 (ICUT (b,e) ((x =+ REF j) m)) = D0 (ICUT (b,e) m) DELETE x` by 480 (REWRITE_TAC [EXTENSION,IN_DELETE] 481 \\ SIMP_TAC std_ss [IN_DEF,ICUT_def,D0,UPDATE_def] \\ STRIP_TAC 482 \\ Cases_on `IRANGE (b,e) x'` \\ ASM_REWRITE_TAC [heap_type_distinct] 483 \\ Cases_on `x' = x` \\ ASM_REWRITE_TAC [heap_type_distinct] 484 \\ simp[]) 485 \\ ASM_SIMP_TAC bool_ss [CARD_DELETE] 486 \\ `x IN D0 (ICUT (b,e) m)` by 487 (ASM_SIMP_TAC std_ss [IN_DEF,D0,ICUT_def] \\ METIS_TAC []) 488 \\ ASM_SIMP_TAC bool_ss [] \\ DECIDE_TAC) 489 THEN1 490 (`D0 (ICUT (b,e) ((x =+ REF j) m)) = D0 (ICUT (b,e) m) DELETE x` by 491 (REWRITE_TAC [EXTENSION,IN_DELETE] 492 \\ SIMP_TAC std_ss [IN_DEF,ICUT_def,D0,UPDATE_def] \\ STRIP_TAC 493 \\ Cases_on `IRANGE (b,e) x'` \\ ASM_REWRITE_TAC [heap_type_distinct] 494 \\ Cases_on `x = x'` \\ ASM_REWRITE_TAC [heap_type_distinct] \\ METIS_TAC []) 495 \\ ASM_SIMP_TAC std_ss [FINITE_DELETE]) 496 THEN1 497 (`~(0 = j)` by DECIDE_TAC \\ ASM_SIMP_TAC std_ss [UPDATE_def]) 498 THEN1 499 (`j < e` by DECIDE_TAC 500 \\ `(m j = EMP) /\ (m k = REF i')` by METIS_TAC [LESS_EQ_REFL] 501 \\ Cases_on `k = j` THEN1 METIS_TAC [heap_type_distinct] 502 \\ Cases_on `k = x` THEN1 METIS_TAC [heap_type_distinct] 503 \\ ASM_SIMP_TAC std_ss [UPDATE_def]) 504 THEN1 505 (FULL_SIMP_TAC bool_ss [roots_inv_def] 506 \\ ASM_REWRITE_TAC [apply_apply] 507 \\ Q.EXISTS_TAC `swap j x o v'` \\ REWRITE_TAC [] 508 \\ REWRITE_TAC [GSYM (SIMP_CONV std_ss [] ``(f o g) o h``),swap_swap] 509 \\ SIMP_TAC std_ss [] 510 \\ SIMP_TAC std_ss [UPDATE_def] 511 \\ `m j = EMP` by METIS_TAC [LESS_OR_EQ,LESS_EQ_REFL,cheney_inv_def] 512 \\ `~isREF(m j) /\ ~isREF(m x)` by METIS_TAC [heap_type_distinct,isREF_def] 513 \\ `(v' j = j) /\ (v' x = x)` by METIS_TAC [] 514 \\ STRIP_TAC THEN1 515 (SIMP_TAC std_ss [FUN_EQ_THM,swap_def] \\ STRIP_TAC 516 \\ `!k. v' (v' k) = k` by FULL_SIMP_TAC std_ss [FUN_EQ_THM] 517 \\ Cases_on `x' = r''` \\ Cases_on `x' = h` \\ METIS_TAC []) 518 \\ STRIP_TAC THENL [ 519 STRIP_TAC \\ Cases_on `x = k` \\ ASM_SIMP_TAC bool_ss [isREF_def,heap_type_11] 520 \\ Cases_on `k = j` \\ ASM_SIMP_TAC bool_ss [heap_type_distinct] 521 \\ REPEAT STRIP_TAC THENL [ 522 `b <=i /\ i <= j ==> RANGE(b,j+1)j` by (REPEAT (POP_ASSUM (K ALL_TAC)) 523 \\ SIMP_TAC std_ss [RANGE_def] \\ DECIDE_TAC) 524 \\ METIS_TAC [], 525 `~RANGE(b,j)k` by METIS_TAC [RANGE_simp] 526 \\ `v' k = k` by METIS_TAC [isREF_def] 527 \\ ASM_SIMP_TAC bool_ss [swap_def]], 528 STRIP_TAC \\ Cases_on `k = x` \\ ASM_SIMP_TAC bool_ss [heap_type_11] 529 THEN1 (SIMP_TAC std_ss [swap_def] \\ METIS_TAC []) 530 \\ Cases_on `k = j` \\ ASM_SIMP_TAC bool_ss [heap_type_distinct] 531 \\ REPEAT STRIP_TAC \\ `v' k = i'` by METIS_TAC [] 532 \\ ASM_SIMP_TAC std_ss [] 533 \\ `R1 m i'` by METIS_TAC [R1] 534 \\ `RANGE(b,j)i'` by METIS_TAC [cheney_inv_def] 535 \\ `~(j = i') /\ ~(x = i')` by METIS_TAC [] 536 \\ ASM_SIMP_TAC std_ss [swap_def]]) 537 THEN1 (SIMP_TAC std_ss [RANGE_def,IN_DEF] \\ DECIDE_TAC) 538 THEN1 539 (ASM_SIMP_TAC std_ss [DR0,D0,R0,ICUT_def,FUN_EQ_THM,UPDATE_def] \\ STRIP_TAC 540 \\ Cases_on `IRANGE (b,e) x'` \\ ASM_REWRITE_TAC [] 541 \\ Cases_on `x = x'` \\ ASM_SIMP_TAC std_ss [heap_type_11] THEN1 METIS_TAC []) 542 THEN1 (SIMP_TAC bool_ss [UPDATE_def]) 543 THEN1 (IMP_RES_TAC LESS_EQ_TRANS 544 \\ ASM_SIMP_TAC std_ss [D0,CUT_def,RANGE_def,UPDATE_def] \\ METIS_TAC []) 545 THEN1 546 (Cases_on `a = x` \\ FULL_SIMP_TAC bool_ss [] THEN1 METIS_TAC [heap_type_distinct] 547 \\ `j < e` by DECIDE_TAC 548 \\ `m j = EMP` by METIS_TAC [LESS_EQ_REFL] 549 \\ Cases_on `a = j` \\ FULL_SIMP_TAC bool_ss [] THEN1 METIS_TAC [heap_type_distinct] 550 \\ ASM_SIMP_TAC std_ss [UPDATE_def]) 551 THEN1 SIMP_TAC std_ss [UPDATE_def]); 552 553val abs_update_lemma = prove( 554 ``!m i x y d x' y'. 555 (m i = DATA (x,y,d)) /\ (m 0 = EMP) /\ 556 (if x = 0 then x' = 0 else (m x = REF x') /\ D0 m x') /\ 557 (if y = 0 then y' = 0 else (m y = REF y') /\ D0 m y') ==> 558 (abs ((i =+ DATA (x',y',d))m) = abs m)``, 559 REWRITE_TAC [FUN_EQ_THM,D0] \\ REPEAT STRIP_TAC 560 \\ `?a0 x0 y0 D0. x'' = (a0,x0,y0,D0)` by METIS_TAC [PAIR] 561 \\ ASM_SIMP_TAC bool_ss [abs_def,UPDATE_thm] 562 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC THENL [ 563 Cases_on `a0 = i` THENL [ 564 FULL_SIMP_TAC std_ss [heap_type_11] \\ STRIP_TAC 565 THENL [Cases_on `x = 0`,Cases_on `y = 0`] 566 \\ FULL_SIMP_TAC bool_ss [ADDR_def] \\ METIS_TAC [ADDR_def], 567 FULL_SIMP_TAC std_ss [heap_type_11] 568 \\ Cases_on `k = i` \\ Cases_on `k' = i` 569 \\ FULL_SIMP_TAC bool_ss [ADDR_def]], 570 Cases_on `a0 = i` THENL [ 571 FULL_SIMP_TAC std_ss [heap_type_11] \\ STRIP_TAC 572 THENL [Cases_on `x = 0`,Cases_on `y = 0`] 573 \\ FULL_SIMP_TAC bool_ss [ADDR_def] \\ METIS_TAC [ADDR_def], 574 FULL_SIMP_TAC std_ss [heap_type_11] \\ STRIP_TAC 575 \\ Cases_on `k = i` \\ Cases_on `k' = i` 576 \\ FULL_SIMP_TAC bool_ss [ADDR_def] \\ METIS_TAC [ADDR_def]]]); 577 578val maintain_lemma = prove( 579 ``!b i j j2 m x y. 580 b <= i /\ i <= j /\ 581 RANGE (i,j) SUBSET (r UNION D1 (CUT (b,i) m)) /\ 582 RANGE (j,j2) SUBSET {x;y} ==> 583 RANGE (i + 1,j2) SUBSET (r UNION D1 (CUT (b,i + 1) ((i =+ DATA (x,y,d)) m)))``, 584 SIMP_TAC bool_ss [SUBSET_DEF,IN_UNION,NOT_IN_EMPTY,IN_INSERT] 585 \\ SIMP_TAC bool_ss [IN_DEF,D1,CUT_def] \\ REPEAT STRIP_TAC 586 \\ Cases_on `r x'` \\ ASM_REWRITE_TAC [] 587 \\ sg `RANGE (j,j2) x' \/ RANGE (i,j) x'` THENL [ 588 FULL_SIMP_TAC std_ss [RANGE_def] \\ DECIDE_TAC, 589 `RANGE (b,i + 1) i` by (FULL_SIMP_TAC std_ss [RANGE_def] \\ DECIDE_TAC) 590 \\ Q.EXISTS_TAC `i` \\ ASM_SIMP_TAC std_ss [APPLY_UPDATE_THM,heap_type_11] \\ METIS_TAC [], 591 RES_TAC \\ Cases_on `RANGE(b,i)k` \\ FULL_SIMP_TAC std_ss [heap_type_distinct] 592 \\ `RANGE (b,i + 1) k /\ ~(i = k)` by (FULL_SIMP_TAC std_ss [RANGE_def] \\ DECIDE_TAC) 593 \\ Q.EXISTS_TAC `k` \\ ASM_SIMP_TAC std_ss [UPDATE_def,heap_type_11] \\ METIS_TAC []]); 594 595val RANGE_split = prove( 596 ``j <= j' ==> j' <= j'' ==> (RANGE(j,j'') = RANGE (j,j') UNION RANGE(j',j''))``, 597 REWRITE_TAC [EXTENSION,IN_UNION] \\ SIMP_TAC std_ss [IN_DEF,RANGE_def] \\ DECIDE_TAC); 598 599val RANGE_lemmas = store_thm("RANGE_lemmas", 600 ``!n. (RANGE(n,n+1) = {n}) /\ (RANGE(n,n) = {})``, 601 REWRITE_TAC [EXTENSION,IN_INSERT,NOT_IN_EMPTY] 602 \\ SIMP_TAC bool_ss [RANGE_def,IN_DEF] \\ DECIDE_TAC); 603 604val PATH_CUT_expand = prove( 605 ``!p r b i j m. PATH (r,p) (basic_abs(CUT (b,i) m)) /\ i <= j ==> 606 PATH (r,p) (basic_abs(CUT (b,j) m))``, 607 Induct \\ REWRITE_TAC [PATH_def] \\ REPEAT STRIP_TAC 608 \\ `RANGE (b,i) r ==> RANGE (b,j) r` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 609 \\ FULL_SIMP_TAC bool_ss [CUT_def,basic_abs,IN_DEF] 610 \\ METIS_TAC [heap_type_distinct]); 611 612val reachable_CUT_expand = prove( 613 ``!r b i j m. reachable r (basic_abs (CUT (b,i) m)) x /\ i <= j ==> 614 reachable r (basic_abs (CUT (b,j) m)) x``, 615 SIMP_TAC bool_ss [reachable_def] \\ REPEAT STRIP_TAC \\ METIS_TAC [PATH_CUT_expand]); 616 617val CUT_EQ_EMP_IMP = prove( 618 ``(CUT (b,i) m x = EMP) /\ RANGE(b,i)x ==> (m x = EMP)``, 619 SIMP_TAC std_ss [D0,CUT_def] \\ METIS_TAC []); 620 621val PATH_snoc = prove( 622 ``!ys x y z m. PATH(x,ys++[y])m /\ PATH(y,[z])m ==> PATH(x,ys++[y]++[z])m``, 623 Induct THEN1 (REWRITE_TAC [APPEND,PATH_def] \\ METIS_TAC []) 624 \\ ASM_SIMP_TAC std_ss [PATH_def,APPEND]); 625 626val move_IMP = prove( 627 ``!x j m x' j' m'. (move (x,j,m) = (x',j',m')) ==> j <= j'``, 628 SIMP_TAC std_ss [move_def,LET_DEF] \\ NTAC 6 STRIP_TAC 629 \\ Cases_on `x = 0` \\ ASM_SIMP_TAC std_ss [PAIR_EQ] 630 \\ Cases_on `isREF (m x)` \\ ASM_SIMP_TAC std_ss [PAIR_EQ] 631 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ] \\ SIMP_TAC std_ss [] \\ DECIDE_TAC); 632 633val cheney_inv_step = store_thm("cheney_inv_step", 634 ``cheney_inv(b,b',i,j,j,e,f,m,w,xx,r) /\ ~(i = j) /\ 635 (cheney_step(i,j,e,m) = (i2,j2,e2,m2)) ==> (e2 = e) /\ j <= j2 /\ 636 cheney_inv(b,b',i2,j2,j2,e2,f,m2,w,xx,r)``, 637 REWRITE_TAC [cheney_step_def] 638 \\ `?x y d. getDATA (m i) = (x,y,d)` by METIS_TAC [PAIR] 639 \\ `?x' j' m'. move (x,j,m) = (x',j',m')` by METIS_TAC [PAIR] 640 \\ `?y' j'' m''. move (y,j',m') = (y',j'',m'')` by METIS_TAC [PAIR] 641 \\ ASM_SIMP_TAC std_ss [LET_DEF] 642 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ] 643 \\ SIMP_TAC bool_ss [] 644 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ] 645 \\ REPEAT STRIP_TAC 646 \\ Q.PAT_X_ASSUM `i + 1 = i2` (K ALL_TAC) 647 \\ Q.PAT_X_ASSUM `j'' = j2` (K ALL_TAC) 648 \\ Q.PAT_X_ASSUM `e = e2` (K ALL_TAC) 649 \\ Q.PAT_X_ASSUM `(i =+ DATA (x',y',d)) m'' = m2` (K ALL_TAC) 650 \\ `i <= e` by (FULL_SIMP_TAC bool_ss [cheney_inv_def] \\ DECIDE_TAC) 651 \\ Q.PAT_X_ASSUM `_ <> _` (ASSUME_TAC o GSYM) 652 \\ `?ax ay ad. m i = DATA (ax,ay,ad)` by METIS_TAC [m_DATA] 653 \\ `~IRANGE (b,e) i /\ i + 1 <= j /\ b <= i /\ i <= j /\ ~RANGE(b,i)i /\ RANGE(i,j) i` by 654 (FULL_SIMP_TAC bool_ss [cheney_inv_def,IRANGE_def,RANGE_def] \\ DECIDE_TAC) 655 \\ FULL_SIMP_TAC bool_ss [getDATA_def,PAIR_EQ] 656 \\ `{x;y} SUBSET0 D1 (CUT(i,j)m)` by 657 (SIMP_TAC bool_ss [SUBSET0_DEF,INSERT_SUBSET,EMPTY_SUBSET,IN_INSERT] 658 \\ FULL_SIMP_TAC bool_ss [IN_DEF,D1,RANGE_def,cheney_inv_def,CUT_def] 659 \\ `i <= i /\ i < j` by DECIDE_TAC 660 \\ STRIP_TAC \\ DISJ2_TAC \\ Q.EXISTS_TAC `i` \\ ASM_REWRITE_TAC [] \\ METIS_TAC []) 661 \\ `{x;y} SUBSET0 DR0 (ICUT(b,e)m)` by 662 (MATCH_MP_TAC SUBSET0_TRANS \\ METIS_TAC [cheney_inv_def]) 663 \\ `{x} SUBSET0 DR0 (ICUT(b,e)m)` by 664 FULL_SIMP_TAC bool_ss [SUBSET0_DEF,INSERT_SUBSET,EMPTY_SUBSET,IN_INSERT] 665 \\ IMP_RES_TAC move_lemma 666 \\ `{y} SUBSET0 DR0 (ICUT(b,e)m')` by 667 FULL_SIMP_TAC bool_ss [SUBSET0_DEF,INSERT_SUBSET,EMPTY_SUBSET,IN_INSERT] 668 \\ IMP_RES_TAC move_lemma 669 \\ Q.PAT_X_ASSUM `cheney_inv (b,b',i,j,j,e,f,m,w,xx,r)` (fn th => ALL_TAC) 670 \\ Q.PAT_X_ASSUM `cheney_inv (b,b',i,j',j,e,f,m',w,xx,r)` (fn th => ALL_TAC) 671 \\ FULL_SIMP_TAC bool_ss [cheney_inv_def] 672 \\ ASM_SIMP_TAC bool_ss [ICUT_update] THEN1 DECIDE_TAC 673 \\ REPEAT STRIP_TAC 674 THEN1 DECIDE_TAC 675 THEN1 DECIDE_TAC 676 THEN1 677 (`~(k = i)` by DECIDE_TAC \\ ASM_SIMP_TAC std_ss [UPDATE_def]) 678 THEN1 679 (`~(k = i)` by DECIDE_TAC \\ ASM_SIMP_TAC std_ss [UPDATE_def]) 680 THEN1 681 (sg `D0 (CUT (b,j'') ((i =+ DATA (x',y',d)) m'')) = 682 i INSERT D0 (CUT (b,j'') m'')` THENL [ 683 SIMP_TAC std_ss [EXTENSION,D0,CUT_def,IN_INSERT] 684 \\ SIMP_TAC std_ss [IN_DEF,D0,UPDATE_def] \\ STRIP_TAC 685 \\ Cases_on `RANGE (b,j'') x''` \\ ASM_SIMP_TAC std_ss [heap_type_distinct] 686 THEN1 (Cases_on `x'' = i` \\ ASM_SIMP_TAC std_ss [] \\ METIS_TAC []) 687 \\ FULL_SIMP_TAC bool_ss [RANGE_def,IRANGE_def] \\ DECIDE_TAC, 688 ASM_SIMP_TAC std_ss [EXTENSION,IN_INSERT] 689 \\ SIMP_TAC std_ss [RANGE_def,IN_DEF] 690 \\ STRIP_TAC \\ Cases_on `x'' = i` \\ ASM_SIMP_TAC std_ss [] \\ DECIDE_TAC]) 691 THEN1 692 (MATCH_MP_TAC D1_SUBSET0 693 \\ `~RANGE(b,i)i` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 694 \\ ASM_SIMP_TAC bool_ss [CUT_update] 695 \\ sg `D1 (CUT (i,i + 1) ((i =+ DATA (x',y',d))m'')) = {x';y'}` THENL [ 696 ASM_SIMP_TAC std_ss [D1,EXTENSION,IN_INSERT,NOT_IN_EMPTY] 697 \\ ASM_SIMP_TAC std_ss [D1,IN_DEF,CUT_def,RANGE_def,DECIDE ``i<=k/\k<i+1 = (k = i)``] 698 \\ SIMP_TAC bool_ss [UPDATE_def] 699 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC 700 \\ Cases_on `k = i` \\ FULL_SIMP_TAC bool_ss [heap_type_11,heap_type_distinct,PAIR_EQ] 701 \\ METIS_TAC [], 702 ASM_REWRITE_TAC [] 703 \\ `RANGE(b,j') SUBSET RANGE(b,j'')` by 704 (SIMP_TAC std_ss [SUBSET_DEF,IN_DEF,RANGE_def] \\ DECIDE_TAC) 705 \\ FULL_SIMP_TAC std_ss [SUBSET0_DEF,INSERT_SUBSET,EMPTY_SUBSET] 706 \\ METIS_TAC [IN_INSERT,SUBSET_DEF]]) 707 THEN1 708 (MATCH_MP_TAC maintain_lemma \\ Q.EXISTS_TAC `j` 709 \\ ASSUME_TAC (UNDISCH_ALL RANGE_split) 710 \\ ASM_SIMP_TAC bool_ss [UNION_SUBSET] \\ STRIP_TAC 711 THENL [Cases_on `~(x = 0) /\ (m' x = REF j)`,Cases_on `~(y = 0) /\ (m'' y = REF j')`] 712 \\ NTAC 2 (FULL_SIMP_TAC bool_ss 713 [heap_type_11,RANGE_lemmas,INSERT_SUBSET,IN_INSERT,EMPTY_SUBSET])) 714 THEN1 715 (`~(RANGE(i+1,j'')i)` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 716 \\ ASM_SIMP_TAC bool_ss [CUT_update] 717 \\ MATCH_MP_TAC SUBSET0_TRANS 718 \\ Q.EXISTS_TAC `D1 (CUT (i,j'') m'')` \\ ASM_SIMP_TAC bool_ss [] 719 \\ SIMP_TAC std_ss [D1,SUBSET_DEF,SUBSET0_DEF,IN_INSERT] 720 \\ SIMP_TAC std_ss [D1,IN_DEF,CUT_def,RANGE_def] 721 \\ METIS_TAC [DECIDE ``i + 1 <= k /\ k < j'' ==> i <= k /\ k < j''``,heap_type_distinct]) 722 THEN1 723 (Q.PAT_X_ASSUM `R1 m'' = RANGE (b,j'')` (fn th => REWRITE_TAC [GSYM th]) 724 \\ `m'' i = DATA (ax,ay,ad)` by 725 (sg `RANGE (b,j) i /\ RANGE (b,j') i` 726 \\ FULL_SIMP_TAC bool_ss [CUT_def,FUN_EQ_THM] 727 THEN1 (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC)\\ METIS_TAC []) 728 \\ SIMP_TAC std_ss [R1,IN_DEF,CUT_def,RANGE_def,SUBSET_DEF,UPDATE_def,FUN_EQ_THM] 729 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ REPEAT STRIP_TAC \\ METIS_TAC [heap_type_distinct]) 730 THEN1 731 (Cases_on `i = j'''` \\ FULL_SIMP_TAC bool_ss [heap_type_distinct,UPDATE_def] 732 \\ Cases_on `i = i'` \\ FULL_SIMP_TAC bool_ss [heap_type_distinct,UPDATE_def] \\ METIS_TAC []) 733 THEN1 734 (`~(i = 0)` by DECIDE_TAC \\ ASM_SIMP_TAC std_ss [UPDATE_def]) 735 THEN1 736 (MATCH_MP_TAC SUBSET_TRANS \\ Q.EXISTS_TAC `i INSERT RANGE(b,i)` \\ STRIP_TAC 737 THEN1 (REWRITE_TAC [SUBSET_DEF,IN_INSERT] \\ SIMP_TAC std_ss [IN_DEF,RANGE_def] \\ DECIDE_TAC) 738 \\ REWRITE_TAC [INSERT_SUBSET] \\ SIMP_TAC std_ss [IN_DEF] \\ STRIP_TAC THENL [ 739 SIMP_TAC std_ss [reachable_def,basic_abs] 740 \\ FULL_SIMP_TAC bool_ss [SUBSET_DEF,IN_INSERT,IN_UNION] 741 \\ FULL_SIMP_TAC bool_ss [IN_DEF] 742 \\ `(r i) \/ D1 (CUT (b,i) m'') i` by METIS_TAC [] 743 THEN1 METIS_TAC [] \\ IMP_RES_TAC D1_IMP 744 \\ `?t. r t /\ reachable t (basic_abs (CUT (b,i) m'')) h` by METIS_TAC [] 745 \\ `PATH (h,[i]) (basic_abs (CUT (b,i + 1) ((i =+ DATA (x',y',d))m'')))` by 746 (`RANGE (b,i+1) h /\ ~(h = i)` by (FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 747 \\ ASM_SIMP_TAC std_ss [PATH_def,APPEND,IN_DEF,basic_abs,CUT_def,UPDATE_def] 748 \\ METIS_TAC []) 749 \\ Q.EXISTS_TAC `t` \\ FULL_SIMP_TAC bool_ss [reachable_def] \\ DISJ2_TAC 750 THEN1 (Q.EXISTS_TAC `[]` \\ ASM_SIMP_TAC bool_ss [APPEND]) 751 \\ Q.EXISTS_TAC `p ++ [h]` \\ MATCH_MP_TAC PATH_snoc \\ ASM_SIMP_TAC bool_ss [] 752 \\ MATCH_MP_TAC PATH_CUT_expand \\ Q.EXISTS_TAC `i` 753 \\ ASM_SIMP_TAC bool_ss [CUT_update] \\ DECIDE_TAC, 754 FULL_SIMP_TAC std_ss [SUBSET_DEF,IN_DEF] \\ REPEAT STRIP_TAC 755 \\ `?t. r t /\ reachable t (basic_abs (CUT (b,i) m'')) x''` by METIS_TAC [] 756 \\ Q.EXISTS_TAC `t` \\ ASM_SIMP_TAC std_ss [] 757 \\ MATCH_MP_TAC reachable_CUT_expand \\ Q.EXISTS_TAC `i` 758 \\ ASM_SIMP_TAC bool_ss [CUT_update] \\ DECIDE_TAC]) 759 THEN1 760 (`m'' k = REF i'` by METIS_TAC [] 761 \\ Cases_on `k = i` \\ ASM_SIMP_TAC bool_ss [UPDATE_def] 762 \\ `RANGE(b,j'')i` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 763 \\ `D0 (CUT (b,j'') m'') i` by METIS_TAC [] \\ IMP_RES_TAC D0_IMP 764 \\ `F` by METIS_TAC [heap_type_distinct]) 765 THEN1 766 (`!x i j m. D0 (CUT (i,j) m) x ==> D0 m x` by 767 (SIMP_TAC bool_ss [D0,CUT_def] \\ METIS_TAC [heap_type_distinct]) 768 \\ sg `abs ((i =+ DATA (x',y',d))m'') = abs m''` THENL [ 769 MATCH_MP_TAC (GEN_ALL abs_update_lemma) 770 \\ Q.EXISTS_TAC `x` \\ Q.EXISTS_TAC `y` \\ ASM_SIMP_TAC bool_ss [heap_type_11] 771 \\ REPEAT (Q.PAT_X_ASSUM `fgh SUBSET0 jkl` (fn th => ALL_TAC)) 772 \\ `RANGE(b,j) i /\ RANGE(b,j') i` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 773 \\ `(m'' i = m i)` by (FULL_SIMP_TAC bool_ss [CUT_def,FUN_EQ_THM] \\ METIS_TAC []) 774 \\ ASM_SIMP_TAC bool_ss [] \\ STRIP_TAC 775 THEN1 (Cases_on `x = 0` \\ FULL_SIMP_TAC bool_ss [] \\ METIS_TAC []) 776 THEN1 (Cases_on `y = 0` \\ FULL_SIMP_TAC bool_ss [] \\ METIS_TAC []), 777 FULL_SIMP_TAC bool_ss [roots_inv_def] \\ Q.EXISTS_TAC `v` 778 \\ ASM_SIMP_TAC bool_ss [] \\ STRIP_TAC \\ STRIP_TAC 779 \\ `RANGE(b,j'') i` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 780 \\ Cases_on `k = i` \\ ASM_SIMP_TAC std_ss [APPLY_UPDATE_THM,heap_type_distinct] 781 \\ METIS_TAC []])); 782 783val cheney_inv_maintained = (SIMP_RULE std_ss [] o prove)( 784 ``!i j e m. 785 (\(i,j,e,m). 786 !r. cheney_inv(b,b',i,j,j,e,f,m,w,xx,r) ==> 787 !i2 m2. (cheney(i,j,e,m) = (i2,m2)) ==> 788 cheney_inv(b,b',i2,i2,i2,e,f,m2,w,xx,r) /\ j <= i2) (i,j,e,m)``, 789 MATCH_MP_TAC cheney_ind \\ SIMP_TAC std_ss [] \\ NTAC 5 STRIP_TAC 790 \\ `?i2 j2 e2 m2. cheney_step (i,j,e,m) = (i2,j2,e2,m2)` by METIS_TAC [PAIR] 791 \\ ASM_SIMP_TAC std_ss [] \\ Cases_on `(i = j) \/ (e < i)` 792 \\ FULL_SIMP_TAC bool_ss [] \\ NTAC 3 STRIP_TAC \\ ONCE_REWRITE_TAC [cheney_def] 793 THEN1 (REWRITE_TAC [PAIR_EQ] \\ METIS_TAC [LESS_EQ_REFL]) 794 THEN1 (FULL_SIMP_TAC bool_ss [cheney_inv_def] \\ `F` by DECIDE_TAC) 795 \\ FULL_SIMP_TAC std_ss [] \\ IMP_RES_TAC cheney_inv_step \\ METIS_TAC [LESS_EQ_TRANS]); 796 797val move_roots_def = Define ` 798 (move_roots ([],j,m) = ([],j,m)) /\ 799 (move_roots (r::rs,j,m) = 800 let (r,j,m) = move(r,j,m) in 801 let (rs,j,m) = move_roots(rs,j,m) in 802 (r::rs,j,m))`; 803 804val cheney_collect_def = Define ` 805 cheney_collector(i:num,e:num,root,l,u,m) = 806 let u = ~u:bool in 807 let i = (if u then 1+l else 1) in 808 let (root,j,m) = move_roots(root,i,m) in 809 let (j,m) = cheney(i,j,i+l,m) in 810 let m = CUT (i,i+l) m in 811 (j,i+l,root,l,u,m)`; 812 813val CUT_EMPTY = prove( 814 ``!b m. (CUT (b,b) m = \x.EMP) /\ (ICUT (b,b) m = m) /\ 815 (RANGE(b,b) = \x.F) /\ (IRANGE(b,b) = \x.T)``, 816 SIMP_TAC std_ss [FUN_EQ_THM,RANGE_def,CUT_def,ICUT_def,RANGE_def,IRANGE_def] 817 \\ METIS_TAC [DECIDE ``~(b <= n /\ n < b:num)``]); 818 819val FINITE_RANGE = prove( 820 ``!j i. FINITE (RANGE(i,i+j)) /\ (CARD (RANGE(i,i+j)) = j)``, 821 Induct \\ REWRITE_TAC [CUT_EMPTY,ADD_0,FINITE_EMPTY,CARD_EMPTY,GSYM EMPTY_DEF] \\ STRIP_TAC 822 \\ sg `(RANGE (i,i + SUC j) = (i + j) INSERT RANGE (i,i + j)) /\ 823 ~((i + j) IN RANGE (i,i + j))` 824 \\ ASM_SIMP_TAC bool_ss [FINITE_INSERT,CARD_INSERT,EXTENSION,IN_INSERT] 825 \\ SIMP_TAC std_ss [IN_DEF,RANGE_def] \\ DECIDE_TAC); 826 827val FINITE_RANGE = store_thm("FINITE_RANGE", 828 ``!i j. FINITE (RANGE(i,j)) /\ (CARD (RANGE(i,j)) = j - i)``, 829 NTAC 2 STRIP_TAC \\ Cases_on `i <= j` 830 THEN1 (FULL_SIMP_TAC bool_ss [LESS_EQ_EXISTS,FINITE_RANGE] \\ DECIDE_TAC) 831 \\ sg `RANGE (i,j) = EMPTY` \\ ASM_REWRITE_TAC [FINITE_EMPTY,CARD_EMPTY] 832 \\ FULL_SIMP_TAC bool_ss [EXTENSION,NOT_IN_EMPTY] 833 \\ SIMP_TAC std_ss [IN_DEF,RANGE_def] \\ DECIDE_TAC); 834 835val ok_state_IMP_cheney_inv = store_thm("ok_state_IMP_cheney_inv", 836 ``ok_state (i,e6,r,l,u,m) ==> 837 let b = if ~u then 1 + l else 1 in 838 cheney_inv (b,b,b,b,b,b + l,l+l+1,m,m,m,{}) /\ 839 !k. MEM k r ==> {k} SUBSET0 DR0 (ICUT (b,b+l) m)``, 840 REPEAT STRIP_TAC \\ FULL_SIMP_TAC std_ss [LET_DEF,cheney_inv_def,ok_state_def,CUT_EMPTY] 841 \\ Q.ABBREV_TAC `b = if u then 1 + l else 1` 842 \\ Q.ABBREV_TAC `b2 = if ~u then 1 + l else 1` 843 \\ `(ICUT (b2,b2 + l) m) = m` by 844 (FULL_SIMP_TAC bool_ss [ICUT_def,FUN_EQ_THM,IN_DEF] 845 \\ sg `!k. RANGE(b,i)k ==> IRANGE (b2,b2 + l) k` 846 THENL [ALL_TAC,METIS_TAC []] \\ Q.UNABBREV_TAC `b` \\ Q.UNABBREV_TAC `b2` 847 \\ Cases_on `u` \\ FULL_SIMP_TAC bool_ss [IRANGE_def,RANGE_def] \\ DECIDE_TAC) 848 \\ ASM_REWRITE_TAC [] \\ REPEAT STRIP_TAC 849 THEN1 (Q.UNABBREV_TAC `b2` \\ Cases_on `u` \\ DECIDE_TAC) 850 THEN1 (Q.UNABBREV_TAC `b2` \\ Cases_on `u` \\ DECIDE_TAC) 851 THEN1 852 (Q.PAT_X_ASSUM `!k. ~bb:bool ==> c` MATCH_MP_TAC 853 \\ Cases_on `u` \\ FULL_SIMP_TAC std_ss [IN_DEF,RANGE_def] 854 \\ Q.UNABBREV_TAC `b` \\ Q.UNABBREV_TAC `b2` \\ DECIDE_TAC) 855 THEN1 856 (Q.PAT_X_ASSUM `!k. ~bbb:bool ==> c` MATCH_MP_TAC 857 \\ Cases_on `u` \\ FULL_SIMP_TAC std_ss [IN_DEF,RANGE_def] 858 \\ Q.UNABBREV_TAC `b` \\ Q.UNABBREV_TAC `b2` \\ DECIDE_TAC) 859 THEN1 (SIMP_TAC std_ss [FUN_EQ_THM,D0,heap_type_distinct]) 860 THEN1 (SIMP_TAC std_ss [SUBSET0_DEF,IN_INSERT,SUBSET_DEF] 861 \\ SIMP_TAC std_ss [IN_DEF,D1,heap_type_distinct]) 862 THEN1 (SIMP_TAC std_ss [SUBSET0_DEF,IN_INSERT,SUBSET_DEF] 863 \\ SIMP_TAC std_ss [IN_DEF,D1,heap_type_distinct]) 864 THEN1 (SIMP_TAC std_ss [SUBSET0_DEF,IN_INSERT,SUBSET_DEF] 865 \\ SIMP_TAC std_ss [IN_DEF,D1,heap_type_distinct]) 866 THEN1 867 (FULL_SIMP_TAC std_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT,NOT_IN_EMPTY] 868 \\ FULL_SIMP_TAC std_ss [IN_DEF,DR0,D1,D0,ICUT_def] \\ REPEAT STRIP_TAC 869 \\ `RANGE(b,i)k` by METIS_TAC [heap_type_distinct] 870 \\ Cases_on `x = 0` \\ ASM_SIMP_TAC bool_ss [] 871 \\ `RANGE(b,i)x` by METIS_TAC [heap_type_11,PAIR_EQ] 872 \\ ASM_REWRITE_TAC [] \\ METIS_TAC []) 873 THEN1 (ASM_SIMP_TAC std_ss [FUN_EQ_THM,R1] \\ METIS_TAC [heap_type_distinct]) 874 THEN1 METIS_TAC [heap_type_distinct] 875 THEN1 876 (MATCH_MP_TAC LESS_EQ_TRANS \\ Q.EXISTS_TAC `CARD (RANGE(b,i))` \\ STRIP_TAC 877 THENL [ALL_TAC, REWRITE_TAC [FINITE_RANGE] \\ DECIDE_TAC] 878 \\ MATCH_MP_TAC ((GEN_ALL o RW [AND_IMP_INTRO] o DISCH_ALL o 879 SPEC_ALL o UNDISCH o SPEC_ALL) CARD_SUBSET) 880 \\ FULL_SIMP_TAC std_ss [FINITE_RANGE,SUBSET_DEF,IN_DEF,D0] 881 \\ METIS_TAC [heap_type_distinct]) 882 THEN1 883 (MATCH_MP_TAC ((GEN_ALL o RW [AND_IMP_INTRO] o DISCH_ALL o 884 SPEC_ALL o UNDISCH o SPEC_ALL) SUBSET_FINITE) 885 \\ Q.EXISTS_TAC `RANGE(b,i)` \\ FULL_SIMP_TAC std_ss [D0,SUBSET_DEF,IN_DEF,ICUT_def,FINITE_RANGE] 886 \\ METIS_TAC [heap_type_distinct]) 887 THEN1 888 (Q.PAT_X_ASSUM `!k. ~bbb:bool ==> c` MATCH_MP_TAC 889 \\ Q.UNABBREV_TAC `b` \\ Cases_on `u` \\ FULL_SIMP_TAC bool_ss [RANGE_def,IN_DEF] \\ DECIDE_TAC) 890 THEN1 REWRITE_TAC [GSYM EMPTY_DEF,EMPTY_SUBSET] 891 THEN1 892 (REWRITE_TAC [roots_inv_def] \\ Q.EXISTS_TAC `I` \\ ASM_SIMP_TAC std_ss [apply_I] 893 \\ METIS_TAC [heap_type_distinct]) 894 THEN1 895 (Cases_on `k = 0` THEN1 ASM_SIMP_TAC std_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT,NOT_IN_EMPTY] 896 \\ REWRITE_TAC [SUBSET0_DEF,SUBSET_DEF,IN_INSERT,NOT_IN_EMPTY] 897 \\ RES_TAC \\ RES_TAC \\ FULL_SIMP_TAC std_ss [IN_DEF,DR0,D0,heap_type_11] \\ METIS_TAC [])); 898 899val reachables_def = Define ` 900 reachables rs h (a,x,y,d) = (a,x,y,d) IN h /\ ?r. MEM r rs /\ a IN reachable r h`; 901 902val basic_abs_EQ_abs = prove( 903 ``!m. (!k i. ~(m k = REF i)) ==> (basic_abs m = abs m)``, 904 REWRITE_TAC [FUN_EQ_THM] \\ REPEAT STRIP_TAC 905 \\ `?a y z d. x = (a,y,z,d)` by METIS_TAC [PAIR] 906 \\ ASM_SIMP_TAC std_ss [abs_def,basic_abs] 907 \\ EQ_TAC \\ REPEAT STRIP_TAC THENL [ 908 Q.EXISTS_TAC `y` \\ Q.EXISTS_TAC `z` \\ ASM_REWRITE_TAC [] 909 \\ STRIP_TAC THENL [Cases_on `m y`,Cases_on `m z`] 910 \\ FULL_SIMP_TAC bool_ss [ADDR_def] \\ METIS_TAC [], 911 FULL_SIMP_TAC bool_ss [heap_type_11,PAIR_EQ] 912 \\ STRIP_TAC THENL [Cases_on `m k`,Cases_on `m k'`] 913 \\ FULL_SIMP_TAC bool_ss [ADDR_def] \\ METIS_TAC []]); 914 915val apply_reachables_lemma = prove( 916 ``(!x. f (g x) = x) /\ (!x. g (f x) = x) ==> 917 PATH (r,p ++ [g a]) s ==> PATH (f r,MAP f p ++ [a]) (apply g s)``, 918 STRIP_TAC \\ Q.SPEC_TAC (`r`,`r`) \\ Q.SPEC_TAC (`p`,`p`) \\ Induct 919 \\ ASM_SIMP_TAC std_ss [APPEND,MAP,PATH_def,IN_DEF,apply_def] \\ METIS_TAC []); 920 921val apply_reachables = store_thm("apply_reachables", 922 ``!r f g s. (f o g = I) /\ (g o f = I) ==> 923 (apply g (reachables r s) = reachables (MAP f r) (apply g s))``, 924 REWRITE_TAC [FUN_EQ_THM] \\ REPEAT STRIP_TAC 925 \\ `?a y z d. x = (a,y,z,d)` by METIS_TAC [PAIR] 926 \\ ASM_SIMP_TAC std_ss [reachables_def,IN_DEF,apply_def,reachable_def,MEM_MAP] 927 \\ Cases_on `s (g a,g y,g z,d)` \\ ASM_REWRITE_TAC [] 928 \\ EQ_TAC \\ REPEAT STRIP_TAC \\ FULL_SIMP_TAC std_ss [] 929 THEN1 METIS_TAC [apply_reachables_lemma] 930 THEN1 METIS_TAC [apply_reachables_lemma] 931 THEN1 METIS_TAC [apply_reachables_lemma] 932 \\ Q.EXISTS_TAC `y'` \\ ASM_REWRITE_TAC [] 933 \\ DISJ2_TAC \\ Q.EXISTS_TAC `MAP g p` 934 \\ Q.UNDISCH_TAC `PATH (r',p ++ [a]) (apply g s)` 935 \\ ASM_REWRITE_TAC [] 936 \\ Q.SPEC_TAC (`y'`,`yy`) \\ Induct_on `p` 937 \\ ASM_SIMP_TAC std_ss [APPEND,MAP,PATH_def,IN_DEF,apply_def] \\ METIS_TAC []); 938 939val PATH_CUT = prove( 940 ``!p r x i j m. 941 RANGE(i,j)r /\ ~RANGE(i,j)x /\ PATH (r,p ++ [x]) (abs m) /\ ~(x = 0) /\ (m 0 = EMP) ==> 942 ?s d. PATH(s,[d]) (abs m) /\ RANGE(i,j)s /\ ~RANGE(i,j)d /\ ~(d = 0)``, 943 Induct THEN1 (REWRITE_TAC [APPEND] \\ METIS_TAC []) 944 \\ NTAC 6 STRIP_TAC 945 \\ CONV_TAC (RATOR_CONV (REWRITE_CONV [PATH_def,APPEND])) 946 \\ Cases_on `RANGE(i,j)h` THEN1 METIS_TAC [] 947 \\ REWRITE_TAC [PATH_def] \\ REPEAT STRIP_TAC 948 \\ `~(h = 0)` by (CCONTR_TAC \\ Cases_on `p` 949 \\ FULL_SIMP_TAC bool_ss [APPEND,PATH_def,IN_DEF,abs_def,heap_type_distinct]) 950 \\ METIS_TAC []); 951 952val fix_ADDR = prove( 953 ``!m ax ay az k k' ad b j e. 954 (m ax = DATA (k,k',ad)) /\ (!k. j <= k /\ k < e ==> (m k = EMP)) /\ 955 RANGE (b,e) ax /\ (D1 (CUT (b,j) m) SUBSET0 RANGE (b,j)) /\ (m 0 = EMP) /\ 956 (D0 (CUT (b,j) m) = RANGE (b,j)) ==> 957 (ADDR k ay (m k) = (ay = k)) /\ (ADDR k' az (m k') = (az = k'))``, 958 REPEAT STRIP_TAC THENL [ 959 Cases_on `m k` \\ ASM_SIMP_TAC bool_ss [ADDR_def] 960 \\ Cases_on `j <= ax` THEN1 METIS_TAC [heap_type_distinct,RANGE_def] 961 \\ `RANGE(b,j) ax` by FULL_SIMP_TAC bool_ss [RANGE_def,DECIDE ``~(m<=n) = n < m:num``] 962 \\ `D1 (CUT (b,j) m) k` by (ASM_SIMP_TAC std_ss [D1,CUT_def] \\ METIS_TAC []) 963 \\ FULL_SIMP_TAC bool_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 964 \\ FULL_SIMP_TAC bool_ss [IN_DEF] 965 \\ `RANGE (b,j) k` by METIS_TAC [heap_type_distinct] 966 \\ `D0 (CUT (b,j) m) k` by METIS_TAC [] 967 \\ IMP_RES_TAC D0_IMP \\ METIS_TAC [heap_type_distinct], 968 Cases_on `m k'` \\ ASM_SIMP_TAC bool_ss [ADDR_def] 969 \\ Cases_on `j <= ax` THEN1 METIS_TAC [heap_type_distinct,RANGE_def] 970 \\ `RANGE(b,j) ax` by FULL_SIMP_TAC bool_ss [RANGE_def,DECIDE ``~(m<=n) = n < m:num``] 971 \\ `D1 (CUT (b,j) m) k'` by (ASM_SIMP_TAC std_ss [D1,CUT_def] \\ METIS_TAC []) 972 \\ FULL_SIMP_TAC bool_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 973 \\ FULL_SIMP_TAC bool_ss [IN_DEF] 974 \\ `RANGE (b,j) k'` by METIS_TAC [heap_type_distinct] 975 \\ `D0 (CUT (b,j) m) k'` by METIS_TAC [] 976 \\ IMP_RES_TAC D0_IMP \\ METIS_TAC [heap_type_distinct]]); 977 978val CUT_EQ_DATA_IMP = prove( 979 ``(CUT (i,j) m y = DATA x) ==> (m y = DATA x) /\ RANGE(i,j)y``, 980 SIMP_TAC std_ss [CUT_def] \\ METIS_TAC [heap_type_distinct]); 981 982val PATH_CUT_IMP = prove( 983 ``!p b i j m. 984 (D1 (CUT (i,j) m) SUBSET0 RANGE (i,j)) /\ (D0 (CUT (i,j) m) = RANGE (i,j)) /\ (m 0 = EMP) /\ 985 PATH (b,p) (abs (CUT (i,j) m)) ==> PATH (b,p) (abs m)``, 986 Induct \\ FULL_SIMP_TAC std_ss [PATH_def,IN_DEF,abs_def,CUT_def,APPEND] 987 \\ FULL_SIMP_TAC bool_ss [GSYM CUT_def] \\ REPEAT STRIP_TAC 988 THENL [METIS_TAC [heap_type_distinct],ALL_TAC,METIS_TAC [heap_type_distinct],ALL_TAC] 989 \\ Cases_on `RANGE(i,j)b` \\ FULL_SIMP_TAC std_ss [heap_type_distinct,heap_type_11] 990 \\ FULL_SIMP_TAC std_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 991 \\ FULL_SIMP_TAC std_ss [IN_DEF] 992 \\ `D1 (CUT (i,j) m) k /\ D1 (CUT (i,j) m) k'` by 993 (SIMP_TAC std_ss [D1,CUT_def] \\ METIS_TAC [heap_type_distinct]) 994 \\ `~(k = 0) ==> D0 (CUT (i,j) m) k` by METIS_TAC [] 995 \\ `~(k' = 0) ==> D0 (CUT (i,j) m) k'` by METIS_TAC [] 996 THENL [Q.EXISTS_TAC `k'`,Q.EXISTS_TAC `k`] \\ Q.EXISTS_TAC `d` 997 THENL [DISJ1_TAC,DISJ2_TAC] \\ REWRITE_TAC [] 998 \\ Cases_on `k = 0` \\ Cases_on `k' = 0` \\ FULL_SIMP_TAC std_ss [ADDR_def] 999 \\ IMP_RES_TAC D0_IMP \\ FULL_SIMP_TAC bool_ss [ADDR_def] 1000 \\ METIS_TAC [ADDR_def]); 1001 1002val reachable_IMP = prove( 1003 ``!b m i j x. 1004 (D1 (CUT (i,j) m) SUBSET0 RANGE (i,j)) /\ (D0 (CUT (i,j) m) = RANGE (i,j)) /\ (m 0 = EMP) /\ 1005 reachable b (abs (CUT (i,j) m)) x ==> reachable b (abs m) x``, 1006 REWRITE_TAC [reachable_def] \\ METIS_TAC [PATH_CUT_IMP]); 1007 1008val MAP_INV = prove( 1009 ``!g f. (g o f = I) /\ (f o g = I) ==> !xs ys. (xs = MAP f ys) = (MAP g xs = ys)``, 1010 NTAC 3 STRIP_TAC \\ Induct 1011 \\ Cases_on `ys` \\ ASM_SIMP_TAC std_ss [MAP,NOT_CONS_NIL,CONS_11] 1012 \\ FULL_SIMP_TAC std_ss [FUN_EQ_THM] \\ METIS_TAC []); 1013 1014val move_roots_spec = prove( 1015 ``!a. ((if ~u then a + l else a) = b) ==> 1016 !r j m r' j' m' w ww xx. 1017 cheney_inv (b,b,b,j,b,b+l,f,m,w:num->'a heap_type,xx:num->'a heap_type,ww) /\ 1018 (!k. MEM k r ==> {k} SUBSET0 DR0 (ICUT (b,b + l) m)) /\ 1019 (move_roots (r,j,m) = (r',j',m')) ==> 1020 cheney_inv (b,b,b,j',b,b+l,f,m',w,xx,ww) /\ j <= j' /\ 1021 (!k. MEM k r' /\ ~(k = 0) ==> RANGE (b,j') k) /\ 1022 (!k. RANGE(j,j') k ==> MEM k r') /\ 1023 (!k i. (m k = REF i) ==> (m' k = REF i)) /\ 1024 (LENGTH r = LENGTH r') /\ 1025 (!k. MEM k r /\ ~(k = 0) \/ isREF (m k) ==> isREF(m' k)) /\ 1026 (!k k'. MEM (k,k') (ZIP(r,r')) ==> if k = 0 then k' = 0 else (m' k = REF k'))``, 1027 STRIP_TAC \\ STRIP_TAC \\ Induct THEN1 1028 (ONCE_REWRITE_TAC [EQ_SYM_EQ] 1029 \\ SIMP_TAC std_ss [PAIR_EQ,move_roots_def,MEM,RANGE_lemmas,EMPTY_DEF, 1030 LESS_EQ_REFL,MAP,apply_I,ZIP]) 1031 \\ NTAC 9 STRIP_TAC 1032 \\ `?r' j' m'. move (h,j,m) = (r',j',m')` by METIS_TAC [PAIR] 1033 \\ `?rs3 j3 m3. move_roots (r,j'',m'') = (rs3,j3,m3)` by METIS_TAC [PAIR] 1034 \\ ASM_SIMP_TAC std_ss [move_roots_def,LET_DEF] 1035 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ] \\ SIMP_TAC bool_ss [MEM] \\ STRIP_TAC 1036 \\ `{h} SUBSET0 DR0 (ICUT (b,b + l) m)` by METIS_TAC [] 1037 \\ IMP_RES_TAC move_lemma 1038 \\ `!k. MEM k r ==> {k} SUBSET0 DR0 (ICUT (b,b + l) m'')` by METIS_TAC [] 1039 \\ Q.PAT_X_ASSUM `!j m r'. bb` (STRIP_ASSUME_TAC o UNDISCH_ALL o 1040 RW [GSYM AND_IMP_INTRO] o Q.SPECL [`j''`,`m''`,`rs3`,`j3`,`m3`,`w`,`ww`,`xx`]) 1041 \\ STRIP_TAC THEN1 METIS_TAC [] 1042 \\ STRIP_TAC THEN1 DECIDE_TAC 1043 \\ STRIP_TAC THEN1 1044 (REPEAT STRIP_TAC \\ Cases_on `h = 0` THEN1 METIS_TAC [] \\ FULL_SIMP_TAC bool_ss [] 1045 \\ IMP_RES_TAC D0_IMP \\ FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 1046 \\ STRIP_TAC THEN1 1047 (REPEAT STRIP_TAC \\ Cases_on `k = r''` THEN1 METIS_TAC [] \\ DISJ2_TAC 1048 \\ Cases_on `h = 0` THEN1 METIS_TAC [] \\ FULL_SIMP_TAC bool_ss [] \\ IMP_RES_TAC D0_IMP 1049 \\ Q.PAT_X_ASSUM `!k. RANGE (_,_) k ==> MEM k rs3` MATCH_MP_TAC 1050 \\ Cases_on ` m'' h = REF j` \\ FULL_SIMP_TAC bool_ss [heap_type_11] 1051 \\ FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 1052 \\ STRIP_TAC THEN1 METIS_TAC [] 1053 \\ ASM_SIMP_TAC std_ss [LENGTH,ZIP,MEM] 1054 \\ STRIP_TAC THEN1 1055 (STRIP_TAC \\ Cases_on `isREF(m k)` \\ ASM_SIMP_TAC bool_ss [] THEN1 METIS_TAC [isREF_def] 1056 \\ REPEAT STRIP_TAC THENL [ALL_TAC,METIS_TAC []] 1057 \\ `~(h = 0)` by DECIDE_TAC 1058 \\ FULL_SIMP_TAC bool_ss [move_def,LET_DEF,PAIR_EQ] 1059 \\ Q.PAT_X_ASSUM `!k. bbb ==> isREF (m3 k)` MATCH_MP_TAC \\ DISJ2_TAC 1060 \\ Q.PAT_X_ASSUM `(h =+ REF j) ((j =+ m h) m) = m''` (fn th => REWRITE_TAC [GSYM th]) 1061 \\ SIMP_TAC std_ss [isREF_def,UPDATE_def,heap_type_11]) 1062 \\ REPEAT STRIP_TAC THEN1 METIS_TAC [] 1063 \\ Cases_on `k = 0` \\ ASM_SIMP_TAC bool_ss [] \\ METIS_TAC []); 1064 1065val cheney_inv_setup = store_thm("cheney_inv_setup", 1066 ``cheney_inv (b,b,b,j,b,e,f,m',m,m,{}) ==> cheney_inv (b,j,b,j,j,e,f,m',m',m,RANGE(b,j))``, 1067 SIMP_TAC bool_ss [cheney_inv_def,LESS_EQ_REFL] \\ REPEAT STRIP_TAC 1068 THEN1 METIS_TAC [] THEN1 METIS_TAC [] 1069 THEN1 (REWRITE_TAC [SUBSET_DEF,IN_UNION] \\ SIMP_TAC bool_ss [IN_DEF]) 1070 THEN1 METIS_TAC [] \\ REWRITE_TAC [RANGE_lemmas,EMPTY_SUBSET]); 1071 1072val list_RANGE_aux_def = Define ` 1073 (list_RANGE_aux 0 n = []) /\ 1074 (list_RANGE_aux (SUC m) n = n::list_RANGE_aux m (n+1))`; 1075 1076val list_RANGE_def = Define ` 1077 list_RANGE(i,j) = list_RANGE_aux (j-i) i`; 1078 1079val list_RANGE_aux_thm = prove( 1080 ``!j i k. MEM k (list_RANGE_aux j i) = RANGE(i,i+j) k``, 1081 Induct \\ ASM_REWRITE_TAC [list_RANGE_aux_def,MEM,RANGE_lemmas,ADD_0,EMPTY_DEF] 1082 \\ REWRITE_TAC [RANGE_def] \\ DECIDE_TAC); 1083 1084val list_RANGE_thm = prove( 1085 ``!i j k. MEM k (list_RANGE(i,j)) = RANGE(i,j) k``, 1086 REWRITE_TAC [list_RANGE_def] \\ REPEAT STRIP_TAC \\ Cases_on `i <= j` THENL [ 1087 FULL_SIMP_TAC bool_ss [LESS_EQ_EXISTS] \\ `i + p - i = p` by DECIDE_TAC 1088 \\ FULL_SIMP_TAC bool_ss [LESS_EQ_EXISTS,list_RANGE_aux_thm], 1089 `j - i = 0` by DECIDE_TAC \\ ASM_SIMP_TAC bool_ss [list_RANGE_aux_def,RANGE_def,MEM] 1090 \\ DECIDE_TAC]); 1091 1092val cheney_collector_spec = store_thm("cheney_collector_spec", 1093 ``ok_state(j6,e6,r,l,u,m) /\ (cheney_collector (j6,e6,r,l,u,m) = (j2,e2,r2',l2,u2,m2)) ==> 1094 ok_state(j2,e2,r2',l2,u2,m2) /\ (l = l2) /\ 1095 ?f. (f o f = I) /\ (MAP f r = r2') /\ (f 0 = 0) /\ 1096 (apply f (reachables r (basic_abs m)) = basic_abs m2)``, 1097 ASM_SIMP_TAC std_ss [cheney_collect_def,LET_DEF] 1098 \\ Q.ABBREV_TAC `b = if ~u then 1 + l else 1` 1099 \\ Q.ABBREV_TAC `e = b + l` 1100 \\ `?r' j' m'. move_roots (r,b,m) = (r',j',m')` by METIS_TAC [PAIR] 1101 \\ `?j'' m''. cheney (b,j',e,m') = (j'',m'')` by METIS_TAC [PAIR] 1102 \\ ASM_SIMP_TAC std_ss [] 1103 \\ ONCE_REWRITE_TAC [EQ_SYM_EQ] 1104 \\ SIMP_TAC std_ss [] \\ STRIP_TAC 1105 \\ Q.UNABBREV_TAC `b` 1106 \\ IMP_RES_TAC (SIMP_RULE std_ss [LET_DEF] ok_state_IMP_cheney_inv) 1107 \\ Q.ABBREV_TAC `b = if ~u then 1 + l else 1` 1108 \\ `(if ~u then 1 + l else 1) = b` by METIS_TAC [] 1109 \\ (STRIP_ASSUME_TAC o RW [AND_IMP_INTRO] o 1110 UNDISCH_ALL o RW [GSYM AND_IMP_INTRO] o Q.INST [`f`|->`l+l+1`] o 1111 Q.SPECL [`r`,`b`,`m`,`r'`,`j'`,`m'`,`m`,`{}`,`m`] o UNDISCH o Q.SPEC `1`) move_roots_spec 1112 \\ `cheney_inv (b,j',b,j',j',b + l,l+l+1,m',m',m,RANGE(b,j'))` by METIS_TAC [cheney_inv_setup] 1113 \\ Q.UNABBREV_TAC `e` \\ Q.ABBREV_TAC `e = b + l` 1114 \\ `cheney_inv (b,j',j'',j'',j'',e,l+l+1,m'',m',m,RANGE (b,j')) /\ j' <= j''` by METIS_TAC [cheney_inv_maintained] 1115 \\ STRIP_TAC THEN1 1116 (FULL_SIMP_TAC std_ss [cheney_inv_def,ok_state_def,LET_DEF,IN_DEF] 1117 \\ `!k. RANGE(b,j') k ==> RANGE(b,j'')k` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 1118 \\ REPEAT STRIP_TAC THEN1 METIS_TAC [] THENL [ 1119 Cases_on `RANGE(b,e)k` \\ ASM_SIMP_TAC std_ss [CUT_def] 1120 \\ Q.PAT_X_ASSUM `!k. bb ==> (m'' k = EMP)` MATCH_MP_TAC 1121 \\ FULL_SIMP_TAC std_ss [RANGE_def] \\ DECIDE_TAC, 1122 `D0 (CUT (b,j'') m'') k` by METIS_TAC [] \\ IMP_RES_TAC D0_IMP 1123 \\ Q.EXISTS_TAC `h` \\ Q.EXISTS_TAC `g` \\ Q.EXISTS_TAC `dd` 1124 \\ `RANGE(b,e)k` by (FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 1125 \\ ASM_SIMP_TAC std_ss [CUT_def] 1126 \\ MATCH_MP_TAC SUBSET0_TRANS \\ Q.EXISTS_TAC `D1 (CUT (b,j'') m'')` 1127 \\ ASM_SIMP_TAC std_ss [] 1128 \\ ASM_SIMP_TAC std_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT,NOT_IN_EMPTY] 1129 \\ ASM_SIMP_TAC std_ss [IN_DEF,D1,CUT_def] \\ METIS_TAC []]) 1130 \\ `basic_abs m = abs m` by 1131 (MATCH_MP_TAC basic_abs_EQ_abs \\ FULL_SIMP_TAC bool_ss [ok_state_def,LET_DEF] 1132 \\ METIS_TAC [heap_type_distinct]) 1133 \\ ASM_SIMP_TAC bool_ss [] 1134 \\ Q.PAT_X_ASSUM `cheney_inv (b,b,b,b,b,e,l+l+1,m,m,m,{})` (K ALL_TAC) 1135 \\ Q.PAT_X_ASSUM `cheney_inv (b,j',b,j',j',e,l+l+1,m',m',m,RANGE (b,j'))` (K ALL_TAC) 1136 \\ `m' 0 = EMP` by METIS_TAC [cheney_inv_def] 1137 \\ Q.PAT_X_ASSUM `cheney_inv (b,b,b,j',b,e,l+l+1,m',m,m,{})` (K ALL_TAC) 1138 \\ FULL_SIMP_TAC bool_ss [cheney_inv_def] 1139 \\ `(\x. ?t. t IN RANGE(b,j') /\ x IN reachable t (abs m'')) 1140 SUBSET (0 INSERT RANGE (b,b+l))` by 1141 (Q.UNABBREV_TAC `e` \\ Cases_on `l = 0` THEN1 1142 (`b = j'` by DECIDE_TAC \\ ASM_SIMP_TAC bool_ss [RANGE_lemmas,NOT_IN_EMPTY] 1143 \\ REWRITE_TAC [GSYM EMPTY_DEF,EMPTY_SUBSET]) 1144 \\ REWRITE_TAC [SUBSET_DEF,IN_INSERT] \\ SIMP_TAC std_ss [IN_DEF,reachable_def] 1145 \\ REPEAT STRIP_TAC THEN1 (FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 1146 \\ CCONTR_TAC \\ FULL_SIMP_TAC bool_ss [] 1147 \\ `RANGE (b,b + l) t` by (FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 1148 \\ (STRIP_ASSUME_TAC o UNDISCH_ALL o RW [GSYM AND_IMP_INTRO] o 1149 Q.SPECL [`p`,`t`,`x`,`b`,`b+l`,`m''`]) PATH_CUT 1150 \\ FULL_SIMP_TAC bool_ss [PATH_def,IN_DEF,abs_def] 1151 \\ (Cases_on `j'' <= s` 1152 THEN1 (`s < b + l` by FULL_SIMP_TAC bool_ss [RANGE_def] \\ METIS_TAC [heap_type_distinct]) 1153 \\ `s < j''` by DECIDE_TAC 1154 \\ `RANGE(b,j'')s` by FULL_SIMP_TAC std_ss [RANGE_def] 1155 \\ `D1 (CUT (b,j'') m'') k /\ D1 (CUT (b,j'') m'') k'` by 1156 (FULL_SIMP_TAC std_ss [D1,CUT_def] \\ METIS_TAC []) 1157 \\ `~(k = 0) ==> RANGE(b,j'')k` by 1158 (FULL_SIMP_TAC bool_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 1159 \\ FULL_SIMP_TAC bool_ss [IN_DEF] \\ METIS_TAC []) 1160 \\ `~(k' = 0) ==> RANGE(b,j'')k'` by 1161 (FULL_SIMP_TAC bool_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 1162 \\ FULL_SIMP_TAC bool_ss [IN_DEF] \\ METIS_TAC [])) 1163 THENL [ 1164 `d = k` by 1165 (Cases_on `k = 0` THEN1 METIS_TAC [ADDR_def] 1166 \\ `D0 (CUT (b,j'') m'') k` by METIS_TAC [] 1167 \\ IMP_RES_TAC D0_IMP \\ METIS_TAC [ADDR_def]), 1168 `d = k'` by 1169 (Cases_on `k' = 0` THEN1 METIS_TAC [ADDR_def] 1170 \\ `D0 (CUT (b,j'') m'') k'` by METIS_TAC [] 1171 \\ IMP_RES_TAC D0_IMP \\ METIS_TAC [ADDR_def])] 1172 \\ `~RANGE(b,j'')d` by (FULL_SIMP_TAC bool_ss [RANGE_def] \\ DECIDE_TAC) 1173 \\ METIS_TAC []) 1174 \\ `basic_abs (CUT(b,e)m'') = reachables r' (abs m'')` by 1175 (REWRITE_TAC [METIS_PROVE [PAIR] ``!f g. (f = g) = !x y z d. f (x,y,z,d) = g (x,y,z,d)``] 1176 \\ ASM_SIMP_TAC bool_ss [reachables_def] 1177 \\ FULL_SIMP_TAC bool_ss [SUBSET_DEF,IN_INSERT] 1178 \\ FULL_SIMP_TAC bool_ss [IN_DEF,basic_abs,abs_def] 1179 \\ REPEAT STRIP_TAC \\ EQ_TAC \\ STRIP_TAC THENL [ 1180 IMP_RES_TAC CUT_EQ_DATA_IMP 1181 \\ ASM_SIMP_TAC std_ss [heap_type_11] 1182 \\ Cases_on `x = 0` THEN1 (`F` by METIS_TAC [heap_type_distinct]) 1183 \\ Cases_on `j'' <= x` THEN1 (`F` by METIS_TAC [RANGE_def,heap_type_distinct]) 1184 \\ `RANGE(b,j'')x` by FULL_SIMP_TAC bool_ss [DECIDE ``~(m<=n)=n<m:num``,RANGE_def] 1185 \\ REPEAT STRIP_TAC THENL [ 1186 `D1 (CUT (b,j'') m'') y` by (SIMP_TAC bool_ss [CUT_def,D1] \\ METIS_TAC []) 1187 \\ Cases_on `y = 0` THEN1 METIS_TAC [ADDR_def] 1188 \\ `RANGE(b,j'')y` by 1189 (FULL_SIMP_TAC bool_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 1190 \\ FULL_SIMP_TAC bool_ss [IN_DEF] \\ METIS_TAC []) 1191 \\ `D0 (CUT (b,j'') m'') y` by METIS_TAC [] 1192 \\ IMP_RES_TAC D0_IMP \\ ASM_SIMP_TAC bool_ss [ADDR_def], 1193 `D1 (CUT (b,j'') m'') z` by (SIMP_TAC bool_ss [CUT_def,D1] \\ METIS_TAC []) 1194 \\ Cases_on `z = 0` THEN1 METIS_TAC [ADDR_def] 1195 \\ `RANGE(b,j'')z` by 1196 (FULL_SIMP_TAC bool_ss [SUBSET0_DEF,SUBSET_DEF,IN_INSERT] 1197 \\ FULL_SIMP_TAC bool_ss [IN_DEF] \\ METIS_TAC []) 1198 \\ `D0 (CUT (b,j'') m'') z` by METIS_TAC [] 1199 \\ IMP_RES_TAC D0_IMP \\ ASM_SIMP_TAC bool_ss [ADDR_def], 1200 RES_TAC \\ Q.EXISTS_TAC `t` \\ STRIP_TAC THEN1 METIS_TAC [] 1201 \\ MATCH_MP_TAC reachable_IMP 1202 \\ Q.EXISTS_TAC `b` \\ Q.EXISTS_TAC `j''` \\ ASM_SIMP_TAC bool_ss [] 1203 \\ sg `abs (CUT (b,j'')m'') = basic_abs (CUT (b,j'') m'')` 1204 THENL [ALL_TAC,METIS_TAC []] 1205 \\ MATCH_MP_TAC (GSYM basic_abs_EQ_abs) 1206 \\ SIMP_TAC bool_ss [CUT_def] \\ NTAC 2 STRIP_TAC 1207 \\ Cases_on `RANGE(b,j'')k` \\ ASM_SIMP_TAC bool_ss [heap_type_distinct] 1208 \\ `D0 (CUT (b,j'') m'') k` by METIS_TAC [] 1209 \\ IMP_RES_TAC D0_IMP \\ ASM_SIMP_TAC bool_ss [heap_type_distinct]], 1210 Q.UNABBREV_TAC `e` \\ Cases_on `r'' = 0` THENL [ 1211 FULL_SIMP_TAC bool_ss [reachable_def] THEN1 METIS_TAC [heap_type_distinct] 1212 \\ FULL_SIMP_TAC bool_ss [PATH_def,APPEND,IN_DEF,abs_def] 1213 \\ Cases_on `p` \\ FULL_SIMP_TAC bool_ss [PATH_def,APPEND,IN_DEF,abs_def] 1214 \\ METIS_TAC [heap_type_distinct], 1215 `(x = 0) \/ RANGE (b,b + l) x` by METIS_TAC [] 1216 THEN1 METIS_TAC [heap_type_distinct] 1217 \\ ASM_SIMP_TAC bool_ss [CUT_def,heap_type_11,PAIR_EQ] 1218 \\ FULL_SIMP_TAC bool_ss [GSYM AND_IMP_INTRO] 1219 \\ `!k. j'' <= k /\ k < b + l ==> (m'' k = EMP)` by METIS_TAC [] 1220 \\ `(ADDR k y (m'' k) = (y = k)) /\ (ADDR k' z (m'' k') = (z = k'))` by 1221 (MATCH_MP_TAC fix_ADDR \\ Q.EXISTS_TAC `x` \\ Q.EXISTS_TAC `d` \\ Q.EXISTS_TAC `b` 1222 \\ Q.EXISTS_TAC `j''` \\ Q.EXISTS_TAC `b+l` \\ ASM_SIMP_TAC bool_ss []) 1223 \\ FULL_SIMP_TAC bool_ss []]]) 1224 \\ Q.PAT_X_ASSUM `roots_inv (b,j'',m'',abs m)` (STRIP_ASSUME_TAC o RW [roots_inv_def]) 1225 \\ Q.EXISTS_TAC `v` \\ ASM_SIMP_TAC bool_ss [apply_apply] 1226 \\ `apply v (reachables r (apply v (abs m''))) = 1227 reachables (MAP v r) (apply v (apply v (abs m'')))` by METIS_TAC [apply_reachables] 1228 \\ ASM_SIMP_TAC bool_ss [apply_apply,apply_I] 1229 \\ `v 0 = 0` by 1230 (`~isREF(m'' 0)` by METIS_TAC [isREF_def,heap_type_distinct] 1231 \\ `~RANGE(b,j'')0` by (REWRITE_TAC [RANGE_def] \\ DECIDE_TAC) 1232 \\ METIS_TAC []) 1233 \\ ASM_SIMP_TAC bool_ss [] 1234 \\ ONCE_REWRITE_TAC [METIS_PROVE [] ``b /\ c = b /\ (b ==> c:bool)``] 1235 \\ SIMP_TAC bool_ss [] 1236 \\ `!k k'. MEM (k,k') (ZIP (r,r')) ==> (v k = k')` by METIS_TAC [] 1237 \\ Q.UNDISCH_TAC `!k k'. MEM (k,k') (ZIP (r,r')) ==> (v k = k')` 1238 \\ Q.UNDISCH_TAC `LENGTH r = LENGTH r'` 1239 \\ REPEAT (POP_ASSUM (K ALL_TAC)) \\ Q.SPEC_TAC (`r'`,`ys`) \\ Q.SPEC_TAC (`r`,`xs`) 1240 \\ Induct THENL [ALL_TAC,STRIP_TAC] \\ Cases 1241 \\ SIMP_TAC std_ss [LENGTH,DECIDE ``~(0 = SUC n)``,MAP,ADD,EQ_ADD_RCANCEL,ZIP,MEM,CONS_11] 1242 \\ METIS_TAC [PAIR_EQ]); 1243 1244val _ = export_theory(); 1245