1structure decidable_separationLogicLib :> decidable_separationLogicLib = 2struct 3 4open HolKernel Parse boolLib bossLib; 5 6(* 7quietdec := true; 8loadPath := 9 (concat Globals.HOLDIR "/examples/decidable_separationLogic/src") :: 10 !loadPath; 11 12map load ["finite_mapTheory", "relationTheory", "congLib", "sortingTheory", 13 "rich_listTheory", "decidable_separationLogicTheory", "listLib", 14 "decidable_separationLogicLibTheory", "optionLib", "stringLib"]; 15show_assums := true; 16*) 17 18open finite_mapTheory relationTheory pred_setTheory congLib sortingTheory 19 listTheory rich_listTheory decidable_separationLogicTheory listLib 20 decidable_separationLogicLibTheory listSyntax; 21 22 23(* 24quietdec := false; 25*) 26 27 28val INFINITE_UNIV___THMs = ref ([]:thm list); 29 30 31fun DUMMY_CONV t = 32 let 33 val v = mk_var("XXXX", type_of t); 34 val thm = mk_thm ([], mk_eq (t, v)) 35 in 36 thm 37 end; 38 39 40 41val swap_cs = reduceLib.num_compset (); 42val _ = computeLib.add_thms [SWAP_REWRITES, APPEND] 43 swap_cs; 44 45val ds_direct_cs = reduceLib.num_compset (); 46val _ = computeLib.add_thms [MAP, PF_TURN_EQ_def, SAFE_MAP_THM] 47 ds_direct_cs; 48 49 50(* 51val sf_points_to_list_cs = reduceLib.num_compset (); 52val _ = computeLib.add_thms [SF_POINTS_TO_LIST_def, SAFE_FILTER_THM, MAP, APPEND, 53 DISJOINT_LIST_PRODUCT_def, pairTheory.UNCURRY, pairTheory.FST, pairTheory.SND] 54 sf_points_to_list_cs; 55*) 56 57fun SMALLFOOT_ERR s = 58 raise HOL_ERR {message = s, origin_function = "", origin_structure = "decidable_separationLogicLib"} 59 60 61 62(************************************************************ 63 Term consts 64*************************************************************) 65 66val LIST_DS_ENTAILS_term = ``LIST_DS_ENTAILS``; 67val pf_true_term = ``pf_true``; 68val pf_equal_term = ``pf_equal``; 69val pf_unequal_term = ``pf_unequal``; 70 71val sf_star_term = ``sf_star``; 72val sf_emp_term = ``sf_emp``;; 73val sf_ls_term = ``sf_ls``; 74val sf_points_to_term = ``sf_points_to``; 75val sf_tree_term = ``sf_tree``; 76val sf_bin_tree_term = ``sf_bin_tree``; 77 78val dse_var_term = ``dse_var``; 79val dse_const_term = ``dse_const``; 80val dsv_nil_term = ``dsv_nil``; 81val dse_nil_term = ``dse_nil``; 82 83 84(************************************************************ 85 destructors 86************************************************************) 87local 88 fun strip_cons_int l t = 89 if not (listSyntax.is_cons t) then (l, t) else 90 let 91 val (e, t') = listSyntax.dest_cons t 92 in 93 strip_cons_int (l@[e]) t' 94 end 95in 96 val strip_cons = strip_cons_int [] 97end; 98 99fun list_mk_cons [] b = b | 100 list_mk_cons (t::tL) b = 101 listSyntax.mk_cons (t, list_mk_cons tL b); 102 103 104fun dest_LIST_DS_ENTAILS t = 105 let 106 val (f, args) = strip_comb t; 107 val _ = if same_const f LIST_DS_ENTAILS_term then () else 108 (SMALLFOOT_ERR "NO DEST_LIST_ENTAILS!"); 109 val _ = if (length args = 3) then () else 110 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 111 val (pre, ante, cons) = (el 1 args, el 2 args, el 3 args); 112 val (c1, c2) = pairLib.dest_pair pre; 113 val (ante_pf, ante_sf) = pairLib.dest_pair ante; 114 val (cons_pf, cons_sf) = pairLib.dest_pair cons; 115 in 116 (c1, c2, ante_pf, ante_sf, cons_pf, cons_sf) 117 end; 118 119 120 121fun dest_pf_equal pf = 122 let 123 val (f, args) = strip_comb pf; 124 val _ = if same_const f pf_equal_term then () else 125 (SMALLFOOT_ERR "NO PF_EQUAL!"); 126 val _ = if (length args = 2) then () else 127 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 128 in 129 (hd args, hd (tl args)) 130 end; 131 132 133fun dest_pf_unequal pf = 134 let 135 val (f, args) = strip_comb pf; 136 val _ = if same_const f pf_unequal_term then () else 137 (SMALLFOOT_ERR "NO PF_UNEQUAL!"); 138 val _ = if (length args = 2) then () else 139 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 140 in 141 (hd args, hd (tl args)) 142 end; 143 144 145(* 146 val sf = ``sf_ls f e1 e2`` 147*) 148fun dest_sf_ls sf = 149 let 150 val (f, args) = strip_comb sf; 151 val _ = if same_const f sf_ls_term then () else 152 (SMALLFOOT_ERR "NO SF_LIST!"); 153 val _ = if (length args = 3) then () else 154 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 155 in 156 (el 1 args, el 2 args, el 3 args) 157 end 158 159 160(* 161 val sf = ``sf_bin_tree (f1,f2) e`` 162 val sf = ``sf_bin_tree fL e`` 163*) 164fun dest_sf_bin_tree sf = 165 let 166 val (f, args) = strip_comb sf; 167 val _ = if same_const f sf_bin_tree_term then () else 168 (SMALLFOOT_ERR "NO SF_BIN_TREE!"); 169 val _ = if (length args = 2) then () else 170 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 171 val (f1,f2) = pairLib.dest_pair (el 1 args) 172 val _ = if f1 = f2 then (SMALLFOOT_ERR "NO SF_BIN_TREE!") else (); 173 in 174 (f1,f2, el 2 args, el 1 args) 175 end 176 177 178(* 179 val sf = ``sf_tree (f1::f2::l) e1 e2`` 180 val sf = ``sf_ls f e1 e2`` 181 val sf = ``sf_bin_tree (f1,f2) e`` 182 val sf = ``sf_bin_tree fL e`` 183*) 184fun dest_sf_tree sf = 185 let 186 val (f, args) = strip_comb sf; 187 val _ = if same_const f sf_tree_term then () else 188 (SMALLFOOT_ERR "NO SF_TREE!"); 189 val _ = if (length args = 3) then () else 190 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 191 val p = strip_cons (el 1 args) 192 193 in 194 (p, el 2 args, el 3 args) 195 end 196 197 198fun dest_sf_tree_ext sf = 199 let 200 val (p, es, e) = dest_sf_tree sf; 201 in 202 (sf, p, es, e) 203 end handle _ => 204 let 205 val (f1, f2, e, _) = dest_sf_bin_tree sf; 206 val (_, typeL) = (dest_type (type_of e)); 207 val es = inst [alpha |-> el 1 typeL, beta |-> el 2 typeL] ``dse_nil:('a, 'b) ds_expression``; 208 in 209 (sf, ([f1,f2], mk_list ([], type_of f1)), es, e) 210 end handle _ => 211 let 212 val (f, e, es) = dest_sf_ls sf; 213 in 214 (sf, ([f], mk_list ([], type_of f)), es, e) 215 end; 216 217 218(* 219 val sf = ``sf_points_to e ((f1, e1)::(f2,e2)::l)`` 220*) 221fun dest_sf_points_to sf = 222 let 223 val (f, args) = strip_comb sf; 224 val _ = if same_const f sf_points_to_term then () else 225 (SMALLFOOT_ERR "NO POINTS_TO!"); 226 val _ = if (length args = 2) then () else 227 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 228 val (l1, l2) = strip_cons (el 2 args); 229 val l1' = map pairLib.dest_pair l1; 230 in 231 (el 1 args, el 2 args, l1', l2) 232 end 233 234 235fun dest_dse_var t = 236 let 237 val (f, args) = strip_comb t; 238 val _ = if same_const f dse_var_term then () else 239 (SMALLFOOT_ERR "NO VAR!"); 240 val _ = if (length args = 1) then () else 241 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 242 in 243 (hd args) 244 end; 245 246fun dest_dse_const t = 247 let 248 val (f, args) = strip_comb t; 249 val _ = if same_const f dse_const_term then () else 250 (SMALLFOOT_ERR "NO CONST!"); 251 val _ = if (length args = 1) then () else 252 (SMALLFOOT_ERR "Wrong No. of ARGS!"); 253 in 254 (hd args) 255 end; 256 257val is_pf_true = same_const pf_true_term; 258val is_sf_emp = same_const sf_emp_term; 259val is_pf_equal = can dest_pf_equal; 260val is_pf_unequal = can dest_pf_unequal; 261val is_sf_ls = can dest_sf_ls; 262val is_sf_points_to = can dest_sf_points_to; 263val is_sf_tree = can dest_sf_tree; 264val is_sf_bin_tree = can dest_sf_bin_tree; 265val is_sf_tree_ext = can dest_sf_tree_ext; 266 267val is_dse_var = can dest_dse_var; 268val is_dse_const = can dest_dse_const; 269fun is_dse_nil ex = same_const ex dse_nil_term; 270 271 272fun is_uneq_2 e1 e2 pf = 273 let 274 val (e1', e2') = dest_pf_unequal pf; 275 in 276 ((e1 = e1') andalso (e2 = e2')) orelse 277 ((e2 = e1') andalso (e1 = e2')) 278 end handle _ => false; 279 280fun is_eq_2 e1 e2 pf = 281 let 282 val (e1', e2') = dest_pf_equal pf; 283 in 284 ((e1 = e1') andalso (e2 = e2')) orelse 285 ((e2 = e1') andalso (e1 = e2')) 286 end handle _ => false; 287 288fun is_uneq_nil ex pf = 289 let 290 val (e1, e2) = dest_pf_unequal pf; 291 in 292 ((e1 = ex) andalso (is_dse_nil e2)) orelse 293 ((e2 = ex) andalso (is_dse_nil e1)) 294 end; 295 296 297fun is_pf_equal_refl pf = 298 (let 299 val (e1, e2) = dest_pf_equal pf; 300 in 301 e1 = e2 302 end) handle _ => false 303 304 305fun is_pf_unequal_refl pf = 306 (let 307 val (e1, e2) = dest_pf_unequal pf; 308 in 309 e1 = e2 310 end) handle _ => false 311 312 313fun is_sf_ls_eq sf = 314 (let 315 val (f, e1, e2) = dest_sf_ls sf; 316 in 317 e1 = e2 318 end) handle _ => false 319 320 321fun is_sf_trivial_list sf = 322 let 323 val (f, e1, e2) = dest_sf_ls sf 324 in 325 (e1 = e2) 326 end handle _ => false; 327 328 329fun is_sf_trivial_bin_tree sf = 330 let 331 val (_, _, e, _) = dest_sf_bin_tree sf 332 in 333 is_dse_nil e 334 end handle _ => false; 335 336 337fun is_sf_trivial_tree sf = 338 let 339 val (_, e1, e2) = dest_sf_tree sf 340 in 341 (e1 = e2) 342 end handle _ => false; 343 344 345 346fun is_sf_trivial sf = 347 is_sf_trivial_list sf orelse 348 is_sf_trivial_bin_tree sf orelse 349 is_sf_trivial_tree sf orelse 350 is_sf_emp sf; 351 352 353fun is_pf_trivial pf = 354 is_pf_equal_refl pf orelse 355 is_pf_true pf; 356 357 358fun is_points_to_nil t = 359 let 360 val (e, _, _, _) = dest_sf_points_to t; 361 in 362 is_dse_nil e 363 end handle _ => false; 364 365 366fun pf_eq pf1 pf2 = 367 (if (pf1 = pf2) then (true, false) else 368 if (is_pf_equal pf1) then ( 369 let 370 val (e1, e2) = dest_pf_equal pf1; 371 val (e1', e2') = dest_pf_equal pf2; 372 in 373 ((e1 = e2') andalso (e2 = e1'), true) (*e1 = e1' ... => pf1 = pf2*) 374 end 375 ) else 376 if (is_pf_unequal pf1) then ( 377 let 378 val (e1, e2) = dest_pf_unequal pf1; 379 val (e1', e2') = dest_pf_unequal pf2; 380 in 381 ((e1 = e2') andalso (e2 = e1'), true) (*e1 = e1' ... => pf1 = pf2*) 382 end 383 ) else (false, false)) 384 handle _ => (false, false) 385 386 387 388fun is_dse_nil_list t = 389 let 390 val (_, e1, _) = dest_sf_ls t; 391 in 392 is_dse_nil e1 393 end; 394 395fun is_sf_points_to_ex ex h = 396 let 397 val (ex', _, _, _) = dest_sf_points_to h; 398 in 399 ex' = ex 400 end; 401 402 403(* too strong 404fun is_dse_nil ex = ( 405 (same_const ex dse_nil_term) orelse 406 let 407 val n = dest_dse_const ex; 408 in 409 (same_const n dsv_nil_term) 410 end) handle _ => false; 411*) 412 413 414 415 416 417 418 419(* general helper functions *) 420local 421 fun fun_in_list_help n P [] = NONE 422 | fun_in_list_help n P (e::l) = 423 let 424 val c = (P e) handle _ => false; 425 in 426 if c then (SOME (n, e)) else fun_in_list_help (n+1) P l 427 end 428in 429 fun find_in_list P l = fun_in_list_help 0 P l; 430end 431 432 433local 434 fun fun_in_list_help n P [] = NONE 435 | fun_in_list_help n P (e::l) = 436 let 437 val c = (P e) handle _ => NONE; 438 in 439 if isSome c then (SOME (n, e, valOf c)) else fun_in_list_help (n+1) P l 440 end 441in 442 fun find_in_list_val P l = fun_in_list_help 0 P l; 443end 444 445 446 447 448 449 450 451 452(******************************************** 453 swapping 454*********************************************) 455fun GEN_SWAP_CONV n1 m1 n2 m2 n3 m3 n4 m4 n5 m5 n6 m6 = 456 let 457 val argsL = [n1, m1, n2, m2, n3, m3, n4, m4, n5, m5, n6, m6]; 458 val argTL = map (numSyntax.term_of_int) argsL; 459(* slightly more efficient, but reordering may be confusing when used manually 460 461 val rewrite_thm = ISPECL argTL LIST_DS_ENTAILS___PERM_SWAP_ELEMENTS 462*) 463 val rewrite_thm = ISPECL argTL LIST_DS_ENTAILS___PERM_SWAP_TO_POS 464 in 465 (ONCE_REWRITE_CONV [rewrite_thm] THENC 466 computeLib.CBV_CONV swap_cs) 467 end 468 469 470fun SWAP_CONV p n m = 471 if (p = 0) then GEN_SWAP_CONV n m 0 0 0 0 0 0 0 0 0 0 else 472 if (p = 1) then GEN_SWAP_CONV 0 0 n m 0 0 0 0 0 0 0 0 else 473 if (p = 2) then GEN_SWAP_CONV 0 0 0 0 n m 0 0 0 0 0 0 else 474 if (p = 3) then GEN_SWAP_CONV 0 0 0 0 0 0 n m 0 0 0 0 else 475 if (p = 4) then GEN_SWAP_CONV 0 0 0 0 0 0 0 0 n m 0 0 else 476 if (p = 5) then GEN_SWAP_CONV 0 0 0 0 0 0 0 0 0 0 n m else 477 SMALLFOOT_ERR "Wrong Parameter" 478 479 480 481 482(* EXAMPLE 483 484val t = ``LIST_DS_ENTAILS ([e3;e4], [(e5,e6);(e8,e8)]) ((pf_equal e1 e2::pf_unequal dse_nil e2::pf_equal e1 e2::l),[]) ((pf_equal e1 e2::pf_unequal e1 e2::pf_equal e1 e2::l),[])`` 485 486SWAP_CONV 4 0 1 t 487 488val l1 = [true, false, false]; 489val l2 = [false, true]; 490*) 491 492fun should_turn (pf1, pf2) = 493 if pf1 = pf2 then false else 494 if (is_dse_nil pf1) then (not (is_dse_nil pf2)) else 495 if (is_dse_var pf2) then (not (is_dse_var pf1)) else 496 if (is_dse_const pf1) then (not (is_dse_const pf2)) else 497 (term_to_string pf1 > term_to_string pf2); 498 499 500fun bool_list2term l = 501 let 502 val l' = map (fn b => if b then T else F) l; 503 in 504 mk_list (l', bool) 505 end 506 507 508fun ds_TURN_EQUATIONS_CONV l1 l2 t = 509 let 510 val thm1 = SPECL [bool_list2term l1, bool_list2term l2] LIST_DS_ENTAILS___PF_TURN_EQ 511 val thm2 = PART_MATCH (fst o dest_eq) thm1 t; 512 val thm3 = CONV_RULE (RHS_CONV (computeLib.CBV_CONV ds_direct_cs)) thm2 513 in 514 thm3 515 end 516 517fun ds_TURN_EQUATIONS_TAC l1 l2 = 518 CONV_TAC (ds_TURN_EQUATIONS_CONV l1 l2); 519 520fun ds_AUTO_DIRECT_EQUATIONS_CONV t = 521 let 522 val (_, _, pf, _,pf', _) = dest_LIST_DS_ENTAILS t; 523 val (pfL, _) = strip_cons pf; 524 val (pfL', _) = strip_cons pf'; 525 526 fun dest_eq_uneq sf = dest_pf_unequal sf handle _ => dest_pf_equal sf; 527 528 val l1 = map (fn sf => (should_turn (dest_eq_uneq sf) handle _ => false)) pfL; 529 val l2 = map (fn sf => (should_turn (dest_eq_uneq sf) handle _ => false)) pfL'; 530 in 531 ds_TURN_EQUATIONS_CONV l1 l2 t 532 end; 533 534 535 536 537 538(* Example 539 540 541val t = ``LIST_DS_ENTAILS ([], [(e1,e2);(e9,e9)]) ((pf1::pf_equal e e::pf_true::pf2::pf_equal e' e'::pf3::l),(sf1::sf2::(sf_ls f e e) ::sf3::(sf_points_to e [(f, e)])::(sf_bin_tree (f1, f2) dse_nil)::(sf_tree fL e2 e2)::(sf_ls f e1 e2)::l2)) ((pf1::pfx::pf_equal e e::pf2::pf_equal e' e'::pf3::l),(sf1::sf2::(sf_ls f e2 e2) ::sf3::sf_emp::(sf_points_to e [(f, e)])::(sf_bin_tree (f1, f2) e)::(sf_tree fL e1 e2)::(sf_ls f e e)::l3))`` 542 543 544val t = ``LIST_DS_ENTAILS ([], []) ([], []) ([], [sf_ls f e e])``; 545 546val t3 = 547 ``LIST_DS_ENTAILS ([dse_var 0; dse_var 2],[(dse_var 3,dse_nil)]) 548 ([pf_unequal (dse_var 0) (dse_var 3); 549 pf_unequal (dse_var 4) (dse_var 5); 550 pf_unequal (dse_var 3) (dse_var 2)],[]) 551 ([],[sf_ls "f" (dse_var 2) (dse_var 2)])`` 552*) 553 554fun bool_list2term_list___filter [] (l1, l2) = (l1, l2) | 555 bool_list2term_list___filter (true::l) (l1, l2) = 556 bool_list2term_list___filter l (T::(append l2 l1), []) | 557 bool_list2term_list___filter (false::l) (l1, l2) = 558 bool_list2term_list___filter l (l1, F::l2); 559 560 561fun bool_list2term___filter l = 562 let 563 val (l1, _) = bool_list2term_list___filter l ([], []); 564 val l2 = rev l1; 565 in 566 (mk_list (l2, bool), l2 = []) 567 end; 568 569 570 571 572 573 574fun is_pre_trivial t = 575 let 576 val (e1, e2) = pairLib.dest_pair t; 577 in 578 (e1 = e2) 579 end handle _ => false; 580 581 582fun get_pf_trival_filter pf = 583let 584 val (pfL, _) = strip_cons pf; 585 val fL = map is_pf_trivial pfL; 586in 587 bool_list2term___filter fL 588end; 589 590fun get_sf_trival_filter sf = 591let 592 val (sfL, _) = strip_cons sf; 593 val fL = map is_sf_trivial sfL; 594in 595 bool_list2term___filter fL 596end; 597 598fun get_pre_trival_filter c2 = 599let 600 val (pre, _) = strip_cons c2; 601 val fL = map is_pre_trivial pre; 602in 603 bool_list2term___filter fL 604end; 605 606 607 608val reflexive_cs = computeLib.bool_compset(); 609val _ = computeLib.add_thms [POS_FILTER_THM, PF_TRIVIAL_FILTER_PRED_def, 610 SF_TRIVIAL_FILTER_PRED_THM, pairTheory.FST, pairTheory.SND] reflexive_cs; 611 612 613fun ds_inference_REMOVE_TRIVIAL___CONV t = 614 let 615 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 616 617 val (f1, p1) = get_pre_trival_filter c2; 618 val (f2, p2) = get_pf_trival_filter pf; 619 val (f3, p3) = get_sf_trival_filter sf; 620 val (f4, p4) = get_pf_trival_filter pf'; 621 val (f5, p5) = get_sf_trival_filter sf'; 622 623 val _ = if p1 andalso p2 andalso p3 andalso p4 andalso p5 then SMALLFOOT_ERR "Nothing trivial found!" else (); 624 625 val thm = ISPECL [f1, f2,f3,f4, f5, c1, c2, pf, sf, pf', sf'] INFERENCE_TRIVIAL_FILTER; 626 val thm2 = CONV_RULE (RHS_CONV (computeLib.CBV_CONV reflexive_cs)) thm; 627 in 628 thm2 629 end 630 631 632 633 634 635(* Example 636val t = ``LIST_DS_ENTAILS (e1::c1,c2) ([pf1;pf_unequal e3 e;pf2],[sf_points_to e1 []; sf_points_to dse_nil []]) ([],[])`` 637val t = ``LIST_DS_ENTAILS (e1::e45::e6::e45::dse_nil::c1,c2) ([pf1;pf_unequal e e;pf2],[sf_points_to e3 []; sf_points_to dse_nil [];sf_bin_tree (f1, f2) e1]) ([],[])`` 638*) 639 640val inconsistent_cs = reduceLib.num_compset (); 641val _ = computeLib.add_thms [SWAP_REWRITES] inconsistent_cs; 642 643fun ds_inference_INCONSISTENT___CONV___UNEQUAL t = 644 let 645 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 646 val (pfL, _) = strip_cons pf; 647 val pfOption = find_in_list is_pf_unequal_refl pfL 648 val _ = if isSome pfOption then () else SMALLFOOT_ERR "No disequation (e = e) found!"; 649 val (n, uneq) = valOf pfOption; 650 val (e, _) = dest_pf_unequal uneq; 651 652 val thm = ISPECL [numLib.term_of_int n, e, c1, c2, pf, sf, pf', sf'] INFERENCE_INCONSISTENT_UNEQUAL___EVAL; 653 val thm2 = CONV_RULE (computeLib.CBV_CONV inconsistent_cs) thm; 654 val _ = if ((concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 655 in 656 EQT_INTRO thm2 657 end 658 659 660fun ds_inference_INCONSISTENT___CONV___NIL_POINTS_TO t = 661 let 662 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 663 val (sfL, _) = strip_cons sf; 664 val pfOption = find_in_list is_points_to_nil sfL 665 val _ = if isSome pfOption then () else SMALLFOOT_ERR "Nothing found!"; 666 val (n, uneq) = valOf pfOption; 667 val (_, a, _, _) = dest_sf_points_to uneq; 668 669 val thm = ISPECL [numLib.term_of_int n, a, c1, c2, pf, sf, pf', sf'] INFERENCE_INCONSISTENT___NIL_POINTS_TO___EVAL; 670 val thm2 = CONV_RULE (computeLib.CBV_CONV inconsistent_cs) thm; 671 val _ = if ((concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 672 in 673 EQT_INTRO thm2 674 end 675 676 677fun find_entry n e [] = NONE | 678 find_entry n e (h::l) = if (e = h) then (SOME n) else 679 find_entry (n+1) e l; 680 681fun find_double_entry n [] = NONE | 682 find_double_entry n (h::l) = 683 let 684 val mOpt = (find_entry (n+1) h l); 685 in 686 if (isSome mOpt) then (SOME (n, valOf mOpt, h)) else find_double_entry (n+1) l 687 end; 688 689fun find_match n cL [] = NONE | 690 find_match n cL (h::l) = 691 let 692 val (i, ex, d) = 693 let 694 val (ex, a, _, _) = dest_sf_points_to h; 695 in 696 (0, ex, a) 697 end handle _ => 698 let 699 val (_, _, ex, fL) = dest_sf_bin_tree h; 700 in 701 (1, ex, fL) 702 end; 703 val cOpt = find_entry 0 ex cL; 704 in 705 if (isSome cOpt) then SOME (n, valOf cOpt, i, ex, d) else 706 find_match (n+1) cL l 707 end handle _ => find_match (n+1) cL l; 708 709 710 711fun ds_inference_INCONSISTENT___CONV___precondition_POINTS_TO_BIN_TREE t = 712 let 713 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 714 val (sfL, _) = strip_cons sf; 715 val (c1L, _) = strip_cons c1; 716 val _ = if ((c1L = []) orelse (sfL = [])) then SMALLFOOT_ERR "Nothing found!" else (); 717 718 719 val resOption = find_match 0 c1L sfL; 720 val _ = if isSome resOption then () else SMALLFOOT_ERR "Nothing found!"; 721 val (n, m, i, e, d) = valOf resOption; 722 723 val inf = if i = 0 then 724 INFERENCE_INCONSISTENT___precondition_POINTS_TO___EVAL 725 else 726 INFERENCE_INCONSISTENT___precondition_BIN_TREE___EVAL; 727 728 val thm = ISPECL [numLib.term_of_int m, numLib.term_of_int n, e, d, c1, c2, pf, sf, pf', sf'] inf; 729 val thm2 = CONV_RULE (computeLib.CBV_CONV inconsistent_cs) thm; 730 val _ = if ((concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 731 in 732 EQT_INTRO thm2 733 end; 734 735 736fun ds_inference_INCONSISTENT___CONV___precondition_dse_nil t = 737 let 738 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 739 val (c1L, _) = strip_cons c1; 740 741 742 val cOption = find_in_list is_dse_nil c1L; 743 val _ = if isSome cOption then () else SMALLFOOT_ERR "Nothing found!"; 744 val (n, _) = valOf cOption; 745 746 val thm = ISPECL [numLib.term_of_int n, c1, c2, pf, sf, pf', sf'] 747 INFERENCE_INCONSISTENT___precondition_dse_nil; 748 val thm2 = CONV_RULE (computeLib.CBV_CONV inconsistent_cs) thm; 749 val _ = if ((concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 750 in 751 EQT_INTRO thm2 752 end; 753 754 755fun ds_inference_INCONSISTENT___CONV___precondition_not_all_distinct t = 756 let 757 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 758 val (c1L, _) = strip_cons c1; 759 760 761 val cOption = find_double_entry 0 c1L; 762 val _ = if isSome cOption then () else SMALLFOOT_ERR "Nothing found!"; 763 val (n, m, x) = valOf cOption; 764 765 val thm = ISPECL [numLib.term_of_int n, numLib.term_of_int m, x, c1, c2, pf, sf, pf', sf'] 766 INFERENCE_INCONSISTENT___precondition_distinct; 767 val thm2 = CONV_RULE (computeLib.CBV_CONV inconsistent_cs) thm; 768 val _ = if ((concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 769 in 770 EQT_INTRO thm2 771 end; 772 773 774val ds_inference_INCONSISTENT___CONV = 775 ds_inference_INCONSISTENT___CONV___UNEQUAL ORELSEC 776 ds_inference_INCONSISTENT___CONV___NIL_POINTS_TO ORELSEC 777 ds_inference_INCONSISTENT___CONV___precondition_dse_nil ORELSEC 778 ds_inference_INCONSISTENT___CONV___precondition_POINTS_TO_BIN_TREE ORELSEC 779 ds_inference_INCONSISTENT___CONV___precondition_not_all_distinct; 780 781 782 783(* Example 784val t = ``LIST_DS_ENTAILS ([pf1;pf_unequal e e;pf2],[]) ([],[])`` 785set_goal ([], t) 786*) 787 788fun ds_inference_AXIOM___CONV t = EQT_INTRO (PART_MATCH (I) INFERENCE_AXIOM t); 789 790 791 792 793(* Example 794val t = ``LIST_DS_ENTAILS ([dse_var 4], [(dse_var 1, dse_var 4)]) ([pf_unequal (dse_var 4) dse_nil;pf_equal x1 (dse_var 1); pf_equal (dse_var 1) (dse_var 2)],sfL) ([pf_equal (dse_var 4) (dse_var 2)],[sf_points_to (dse_var 5) [(f, (dse_var 1))]])`` 795 796*) 797 798 799 800 801val subst_cs = reduceLib.num_compset (); 802val _ = computeLib.add_thms [PF_SUBST_def, MAP, SF_SUBST_THM, DS_VAR_SUBST_def, DS_VAR_SUBST_NIL, 803 SWAP_REWRITES, pairTheory.FST, pairTheory.SND] 804 subst_cs; 805 806 807fun is_pf_equal_subst pf = 808 (let 809 val (e1, e2) = dest_pf_equal pf; 810 in 811 (not (e1 = e2)) andalso ((is_dse_var e1) orelse (is_dse_var e2)) 812 end) handle _ => false 813 814fun ds_inference_SUBSTITUTION___CONV t = 815 let 816 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 817 val (pfL, _) = strip_cons pf; 818 val pfOption = find_in_list is_pf_equal_subst pfL 819 val _ = if isSome pfOption then () else SMALLFOOT_ERR "No equation (var s = e) found!"; 820 val (n, uneq) = valOf pfOption; 821 val (e1, e2) = dest_pf_equal uneq; 822 val (inf, e1, e2) = if (is_dse_var e1) then (INFERENCE_SUBSTITUTION___EVAL1, e1, e2) else 823 (INFERENCE_SUBSTITUTION___EVAL2, e2, e1); 824 825 val thm = ISPECL [numLib.term_of_int n, e2, dest_dse_var e1, c1, c2, pf, sf, pf', sf'] inf; 826 val thm2 = CONV_RULE (computeLib.CBV_CONV subst_cs) thm; 827 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 828 in 829 thm2 830 end; 831 832 833 834 835 836 837(*example 838val t = ``LIST_DS_ENTAILS ([e7;e5;e4;e6], []) ([pf_unequal e1 e2;pf1;pf_unequal dse_nil e5;pf2;pf_unequal e1 e2],sfL) ([pf5;pf_unequal e6 e7;pf4;pf1;pf_equal e2 e1;pf_unequal dse_nil e4;pf_unequal e2 e1],pfL')`` 839*) 840 841 842fun find_sf_eq_in_list n ex [] = NONE | 843 find_sf_eq_in_list n ex (h::l) = 844 let 845 val (p1, p2) = pf_eq ex h; 846 in 847 if p1 then (SOME (n, p2)) else 848 find_sf_eq_in_list (n+1) ex l 849 end 850 851 852local 853 854 fun check_in_pre_pf l1 h = 855 let 856 val cOpt = find_sf_eq_in_list 0 h l1; 857 val (n, turn) = valOf cOpt; 858 val cond = (list_mk_comb (``hyp_in_precond``, [if turn then T else F, numLib.term_of_int n])); 859 in 860 SOME cond 861 end handle _ => NONE; 862 863 864 fun check_in_self_pf n l2 h = 865 let 866 val cOpt = find_sf_eq_in_list 0 h l2; 867 val (m, turn) = valOf cOpt; 868 val _ = if (m < n) then () else SMALLFOOT_ERR "To late"; 869 val cond = (list_mk_comb (``hyp_in_self``, [if turn then T else F, numLib.term_of_int m])); 870 in 871 SOME cond 872 end handle _ => NONE; 873 874 875 fun check_c_dse_nil cL h = 876 let 877 val (e1, e2) = dest_pf_unequal h; 878 val (e1, turn) = if is_dse_nil e2 then (e1, true) else 879 if is_dse_nil e1 then (e2, false) else 880 SMALLFOOT_ERR "no dse_nil found"; 881 882 val cOpt = find_entry 0 e1 cL; 883 val n = valOf cOpt; 884 in 885 SOME (list_mk_comb (``hyp_c_dse_nil``, [if turn then T else F, numLib.term_of_int n])) 886 end handle _ => NONE; 887 888 889 fun check_c_unequal cL h = 890 let 891 val (e1, e2) = dest_pf_unequal h; 892 val _ = if (e1 = e2) then SMALLFOOT_ERR "preserve for inconsistence" else (); 893 894 val n1 = valOf (find_entry 0 e1 cL); 895 val n2 = valOf (find_entry 0 e2 cL); 896 in 897 SOME (list_mk_comb (``hyp_c_unequal``, [numLib.term_of_int n1, numLib.term_of_int n2])) 898 end handle _ => NONE; 899 900 901 902 fun get_hypothesis_filter_helper c1 l1 l2 n [] = [] | 903 get_hypothesis_filter_helper c1 l1 l2 n (h::l) = 904 let 905 val condOpt = check_in_pre_pf l1 h; 906 val condOpt = if isSome (condOpt) then condOpt else 907 check_in_self_pf n l2 h; 908 val condOpt = if isSome (condOpt) then condOpt else 909 check_c_dse_nil c1 h; 910 val condOpt = if isSome (condOpt) then condOpt else 911 check_c_unequal c1 h; 912 val cond = if isSome condOpt then valOf condOpt else ``hyp_keep``; 913 in 914 cond::(get_hypothesis_filter_helper c1 l1 l2 (n+1) l) 915 end; 916 917 fun remove_keep l1 l2 [] = l1 | 918 remove_keep l1 l2 (h::l) = 919 if (same_const ``hyp_keep`` h) then 920 remove_keep l1 (h::l2) l 921 else 922 remove_keep (h::(append l2 l1)) [] l 923 924 925in 926 fun get_hypothesis_filter c1 l1 l2 = 927 let 928 val f = get_hypothesis_filter_helper c1 l1 l2 0 l2; 929 val rf = remove_keep [] [] f; 930 val fL = rev rf; 931 val p = (fL = []); 932 val ft = mk_list (fL, ``:hypothesis_rule_cases``); 933 in 934 (ft, p) 935 end 936end; 937 938 939 940val hypothesis_cs = reduceLib.num_compset (); 941val _ = computeLib.add_thms [HYPOTHESIS_RULE_MAP_def, SWAP_REWRITES, PF_TURN_EQ_def, HYPOTHESIS_RULE_COND_THM] 942 hypothesis_cs; 943 944fun ds_inference_HYPOTHESIS___CONV t = 945 let 946 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 947 val (cL, _) = strip_cons c1; 948 val (pfL, _) = strip_cons pf; 949 val (pfL', _) = strip_cons pf'; 950 val (f1, p1) = get_hypothesis_filter cL [] pfL; 951 val (f2, p2) = get_hypothesis_filter cL pfL pfL'; 952 953 val _ = if (p1 andalso p2) then SMALLFOOT_ERR "No common formulas found!" else (); 954 955 val thm = ISPECL [f1, f2, c1, c2, pf, sf, pf', sf'] 956 INFERENCE_HYPOTHESIS___EVAL; 957 val thm2 = CONV_RULE (RHS_CONV (computeLib.CBV_CONV hypothesis_cs)) thm; 958 in 959 thm2 960 end; 961 962 963 964 965 966 967 968 969(*example 970val t = ``LIST_DS_ENTAILS ([], []) (pfL,[sf1;sf2;sf_points_to e1 [("f", b);("g", c)];sf_points_to e2 [("f", b)];sf_bin_tree ("f", "g") e3; sf_bin_tree ("g", "f") e4;sf_points_to e3 [("f", b);("g", c)];sf5;sf_ls "f" e1 e3]++sfL) (pfL',[sf5;sf_points_to e1 [("g", c);("f", b)];sf_points_to e1 [("f", b);("h", c)];sf_points_to e2 [("f", b)];sf_ls "f" e1 e3;sf_points_to e3 [("f", b);("g", c)];sf4;sf_bin_tree ("f", "g") e3; sf_bin_tree ("f", "g") e4;sf1]++sfL)`` 971 972val t = rhs (concl (SIMP_CONV list_ss [] t)) 973*) 974 975local 976 fun find_pairs_helper P n1 n2 l [] l2 r = r 977 | find_pairs_helper P n1 n2 l (e::l1) [] r = 978 find_pairs_helper P (n1+1) 0 l l1 l r 979 | find_pairs_helper P n1 n2 l (e1::l1) (e2::l2) r = 980 if ((P e1 e2) handle _ => false) then 981 find_pairs_helper P n1 (n2+1) l (e1::l1) l2 ((n1, e1, n2, e2)::r) 982 else 983 find_pairs_helper P n1 (n2+1) l (e1::l1) l2 r 984in 985 fun find_pairs P l1 l2 = 986 find_pairs_helper P 0 0 l2 l1 l2 []; 987end 988 989 990local 991 fun adapt_pair_list_to_deletes___map n1 n2 [] = [] | 992 adapt_pair_list_to_deletes___map n1 n2 ((n1', e1, n2', e2)::l) = 993 let val l' = adapt_pair_list_to_deletes___map n1 n2 l in 994 if (n1 = n1') orelse (n2 = n2') then 995 l' 996 else 997 (if n1' > n1 then (n1'-1) else n1', e1, 998 if n2' > n2 then (n2'-1) else n2', e2)::l' 999 end; 1000 1001 fun adapt_pair_list_to_deletes___helper l1 [] = l1 | 1002 adapt_pair_list_to_deletes___helper l1 ((n1, e1, n2, e2)::l) = 1003 adapt_pair_list_to_deletes___helper ((n1, e1, n2, e2)::l1) (adapt_pair_list_to_deletes___map n1 n2 l); 1004in 1005 1006fun adapt_pair_list_to_deletes l = rev (adapt_pair_list_to_deletes___helper [] l); 1007 1008end; 1009 1010 1011fun pred_frame___points_to sf1 sf2 = 1012 let 1013 val (e1, _, a1, aL1) = dest_sf_points_to sf1; 1014 val (e2, _, a2, aL2) = dest_sf_points_to sf2; 1015 in 1016 (e1 = e2) andalso (aL1 = aL2) andalso 1017 (all (fn x => mem x a1) a2) 1018 end; 1019 1020 1021val frame_cs = reduceLib.num_compset (); 1022val _ = listSimps.list_rws frame_cs; 1023val _ = computeLib.add_thms [SWAP_REWRITES, pairTheory.FST, listTheory.ALL_DISTINCT] frame_cs; 1024val _ = computeLib.add_conv (``$=``, 2, stringLib.string_EQ_CONV) frame_cs; 1025val _ = computeLib.add_conv (``$=``, 2, stringLib.char_EQ_CONV) frame_cs; 1026 1027 1028 1029fun ds_inference_FRAME___SINGLE_CONV___sf_points_to (n1, sf1, n2, sf2) t = 1030 let 1031 val (e1, a1, _, _) = dest_sf_points_to sf1; 1032 val (_, a2, _, _) = dest_sf_points_to sf2; 1033 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1034 1035 val thm = ISPECL [e1, numLib.term_of_int n1, a1, numLib.term_of_int n2, a2, c1, c2, pf, sf, pf', sf'] 1036 INFERENCE_STAR_INTRODUCTION___points_to___EVAL 1037 val thm2 = CONV_RULE (computeLib.CBV_CONV frame_cs) thm; 1038 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No conversion"; 1039 in 1040 thm2 1041 end; 1042 1043 1044fun ds_inference_FRAME___CONV___sf_points_to t = 1045 let 1046 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1047 val (sfL, _) = strip_cons sf; 1048 val (sfL', _) = strip_cons sf'; 1049 1050 val pairList = find_pairs pred_frame___points_to sfL sfL'; 1051 val _ = if (pairList = []) then SMALLFOOT_ERR "Nothing found" else (); 1052 1053 val adapt_pairList = adapt_pair_list_to_deletes (rev pairList) 1054 in 1055 EVERY_CONV (map ds_inference_FRAME___SINGLE_CONV___sf_points_to adapt_pairList) t 1056 end; 1057 1058 1059fun pred_frame___list sf1 sf2 = 1060 (sf1 = sf2) andalso (is_sf_ls sf1); 1061 1062 1063fun ds_inference_FRAME___SINGLE_CONV___sf_ls (n1, sf1, n2, sf2) t = 1064 let 1065 val (f, e1, e2) = dest_sf_ls sf1; 1066 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1067 1068 val thm = ISPECL [f, e1, e2, numLib.term_of_int n1, numLib.term_of_int n2, c1, c2, pf, sf, pf', sf'] 1069 INFERENCE_STAR_INTRODUCTION___list___EVAL 1070 val thm2 = CONV_RULE (computeLib.CBV_CONV frame_cs) thm; 1071 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No conversion"; 1072 in 1073 thm2 1074 end; 1075 1076 1077fun ds_inference_FRAME___CONV___sf_ls t = 1078 let 1079 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1080 val (sfL, _) = strip_cons sf; 1081 val (sfL', _) = strip_cons sf'; 1082 1083 val pairList = find_pairs pred_frame___list sfL sfL'; 1084 val _ = if (pairList = []) then SMALLFOOT_ERR "Nothing found" else (); 1085 1086 val adapt_pairList = adapt_pair_list_to_deletes (rev pairList); 1087 in 1088 EVERY_CONV (map ds_inference_FRAME___SINGLE_CONV___sf_ls adapt_pairList) t 1089 end; 1090 1091 1092 1093fun pred_frame___bin_tree sf1 sf2 = 1094 let 1095 val (f11, f12, e1, _) = dest_sf_bin_tree sf1; 1096 val (f21, f22, e2, _) = dest_sf_bin_tree sf2; 1097 in 1098 (e1 = e2) andalso 1099 (((f11 = f21) andalso (f12 = f22)) orelse 1100 ((f12 = f21) andalso (f11 = f22))) 1101 end; 1102 1103 1104 1105fun ds_inference_FRAME___SINGLE_CONV___sf_bin_tree (n1, sf1, n2, sf2) t = 1106 let 1107 val (f11, f12, e1, _) = dest_sf_bin_tree sf1; 1108 val (f21, f22, _, _) = dest_sf_bin_tree sf2; 1109 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1110 1111 val thm = ISPECL [e1, f11, f12, f21, f22, numLib.term_of_int n1, numLib.term_of_int n2, c1, c2, pf, sf, pf', sf'] 1112 INFERENCE_STAR_INTRODUCTION___bin_tree___EVAL 1113 val thm2 = CONV_RULE (computeLib.CBV_CONV frame_cs) thm; 1114 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No conversion"; 1115 in 1116 thm2 1117 end; 1118 1119fun ds_inference_FRAME___CONV___sf_bin_tree t = 1120 let 1121 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1122 val (sfL, _) = strip_cons sf; 1123 val (sfL', _) = strip_cons sf'; 1124 1125 val pairList = find_pairs pred_frame___bin_tree sfL sfL'; 1126 val _ = if (pairList = []) then SMALLFOOT_ERR "Nothing found" else (); 1127 1128 val adapt_pairList = adapt_pair_list_to_deletes (rev pairList); 1129 in 1130 EVERY_CONV (map ds_inference_FRAME___SINGLE_CONV___sf_bin_tree adapt_pairList) t 1131 end; 1132 1133 1134val ds_inference_FRAME___CONV = 1135 (TRY_CONV ds_inference_FRAME___CONV___sf_points_to) THENC 1136 (TRY_CONV ds_inference_FRAME___CONV___sf_ls) THENC 1137 (TRY_CONV ds_inference_FRAME___CONV___sf_bin_tree) 1138 1139 1140 1141 1142fun ds_inference_FRAME___IMPL_CONV___tail t = 1143 let 1144 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1145 val (sfL, sfLr) = strip_cons sf; 1146 val (sfL', sfLr') = strip_cons sf'; 1147 1148 val _ = if (is_nil sfLr orelse not (sfLr = sfLr')) then SMALLFOOT_ERR "Nothing found" else (); 1149 1150 val list_type = dest_list_type (type_of sfLr) 1151 val sfLt = mk_list (sfL, list_type); 1152 val sfLt' = mk_list (sfL', list_type); 1153 1154 val thm = ISPECL [sfLr, c1,c2, pf, sfLt, pf', sfLt'] INFERENCE_STAR_INTRODUCTION___EVAL1 1155 val thm2 = CONV_RULE (computeLib.CBV_CONV frame_cs) thm; 1156 val _ = if (snd (dest_imp (concl thm2)) = t) then () else SMALLFOOT_ERR "No imp-conversion"; 1157 in 1158 thm2 1159 end; 1160 1161 1162fun ds_inference_FRAME___IMPL_CONV___single_step ((n1, x, n2, _),in_thm) = 1163let 1164 val (t1, t2) = dest_imp (concl in_thm); 1165 1166 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t1; 1167 1168 val thm = ISPECL [x, numLib.term_of_int n1, numLib.term_of_int n2, c1, c2, pf, sf, pf', sf'] INFERENCE_STAR_INTRODUCTION___EVAL2; 1169 val thm2 = CONV_RULE (computeLib.CBV_CONV frame_cs) thm; 1170 val thm3 = IMP_TRANS thm2 in_thm 1171in 1172 thm3 1173end; 1174 1175val imp_thm = prove (``!a. a ==> a``, SIMP_TAC std_ss []); 1176 1177fun ds_inference_FRAME___IMPL_CONV___pair t = 1178 let 1179 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1180 val (sfL, _) = strip_cons sf; 1181 val (sfL', _) = strip_cons sf'; 1182 1183 val pairList = find_pairs (fn x => fn y => x = y) sfL sfL'; 1184 val _ = if (pairList = []) then SMALLFOOT_ERR "Nothing found" else (); 1185 val adapt_pairList = adapt_pair_list_to_deletes (rev pairList); 1186 1187 val in_thm = ISPEC t imp_thm; 1188 val thm = foldl ds_inference_FRAME___IMPL_CONV___single_step in_thm adapt_pairList; 1189 in 1190 thm 1191 end; 1192 1193 1194fun ds_inference_FRAME___IMPL_CONV t = 1195 let 1196 val eq_thm = (SOME (ds_inference_FRAME___CONV t)) handle _ => NONE 1197 val t2 = if isSome eq_thm then (rhs (concl (valOf eq_thm))) else t; 1198 val imp1_thm = (SOME (ds_inference_FRAME___IMPL_CONV___tail t2)) handle _ => NONE; 1199 val t3 = if isSome imp1_thm then (fst (dest_imp (concl (valOf imp1_thm)))) else t2; 1200 val imp2_thm = (SOME (ds_inference_FRAME___IMPL_CONV___pair t3)) handle _ => NONE; 1201 1202 val imp_thm = if not (isSome imp2_thm) then imp1_thm else 1203 if not (isSome imp1_thm) then imp2_thm else 1204 SOME (IMP_TRANS (valOf imp2_thm) (valOf imp1_thm)); 1205 1206 val thm = if not (isSome imp_thm) then eq_thm else 1207 if not (isSome eq_thm) then imp_thm else 1208 SOME (CONV_RULE (REWRITE_CONV [GSYM (valOf eq_thm)]) (valOf imp_thm)) 1209 in 1210 valOf thm 1211 end; 1212 1213 1214(*example 1215val t = ``LIST_DS_ENTAILS ([e6], []) ([pf_unequal e1 dse_nil; pf_unequal dse_nil e3;pf_unequal e3 e2],[sf_points_to e1 [("g", e5)];sf_points_to e3 [];sf_ls f e1 e2;sf_ls f e2 e3;sf_points_to e4 []]) ([],[])`` 1216*) 1217 1218 1219val pointsto_skip_term = ``pointsto_skip``; 1220val pointsto_pointsto_term = ``pointsto_pointsto``; 1221val pointsto_tree_term = ``pointsto_tree``; 1222 1223 1224fun get_points_to_list_cond_filter pfL sf = 1225 if is_sf_points_to sf then pointsto_pointsto_term else 1226 let 1227 val (_, _, es, e) = dest_sf_tree_ext sf; 1228 val (n, uneqt) = valOf (find_in_list (is_uneq_2 es e) pfL) 1229 val (e', es') = dest_pf_unequal uneqt 1230 val turn = not (es' = es); 1231 in 1232 list_mk_comb (pointsto_tree_term, [if turn then T else F, numLib.term_of_int n]) 1233 end handle _ => pointsto_skip_term; 1234 1235 1236fun check_unequal_dse_nil_is_necessary cL pfL ex = 1237 not (isSome (find_in_list (is_uneq_nil ex) pfL)) andalso 1238 not (isSome (find_entry 0 ex cL)); 1239 1240fun get_points_to_list_cond_exp sf = 1241 let 1242 val (e1, _, _, _) = dest_sf_points_to sf; 1243 in 1244 e1 1245 end handle _ => 1246 let 1247 val (_, _, _, e1) = dest_sf_tree_ext sf; 1248 in 1249 e1 1250 end; 1251 1252 1253fun map_restrict_points_to_list_cond_filter pfL cL [] _ = [] | 1254 map_restrict_points_to_list_cond_filter pfL cL (f::fL) [] = [] | 1255 map_restrict_points_to_list_cond_filter pfL cL (f::fL) (sf::sfL) = 1256 let 1257 val ex = get_points_to_list_cond_exp sf; 1258 val f' = if check_unequal_dse_nil_is_necessary cL pfL ex then f else pointsto_skip_term; 1259 in 1260 (f' :: (map_restrict_points_to_list_cond_filter pfL (ex::cL) fL sfL)) 1261 end; 1262 1263 1264 1265 1266val sf_points_to_list_cs = reduceLib.num_compset (); 1267val _ = computeLib.add_thms 1268[SF_POINTS_TO_LIST_def, 1269 SAFE_FILTER_THM, SF_POINTS_TO_LIST_COND_FILTER_def, SF_POINTS_TO_LIST_COND_THM, 1270 SWAP_REWRITES] sf_points_to_list_cs; 1271val _ = listSimps.list_rws sf_points_to_list_cs; 1272 1273 1274fun ds_inference_NIL_NOT_LVAL___CONV___overeager over t = 1275 let 1276 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1277 val (cL, _) = strip_cons c1; 1278 val (pfL, _) = strip_cons pf; 1279 val (sfL, _) = strip_cons sf; 1280 1281 val f = map (get_points_to_list_cond_filter pfL) sfL; 1282 val f = if over then f else 1283 map_restrict_points_to_list_cond_filter pfL cL f sfL; 1284 1285 val p = exists (fn x => not (x = pointsto_skip_term)) f; 1286 val _ = if not p then SMALLFOOT_ERR "No new facts!" else () 1287 1288 val ft = mk_list (f, type_of (hd f)); 1289 1290 val thm = ISPECL [ft, c1, c2, pf, sf, pf', sf'] INFERENCE_NIL_NOT_LVAL___EVAL 1291 val thm2 = CONV_RULE (RHS_CONV (computeLib.CBV_CONV sf_points_to_list_cs)) thm; 1292 in 1293 thm2 1294 end; 1295 1296 1297val ds_inference_NIL_NOT_LVAL___CONV = 1298 ds_inference_NIL_NOT_LVAL___CONV___overeager false; 1299 1300 1301 1302 1303 1304 1305(*example 1306val t = ``LIST_DS_ENTAILS ([e2;e1;e4;e6;e5], []) ([pf_unequal e3 e2],[sf_points_to e1 x;sf_points_to e2 x;sf_points_to e3 x;sf_points_to e4 x;sf_ls f e3 e2]) ([],[])`` 1307*) 1308 1309 1310val product_term = `` 1311 (LIST_PRODUCT (SF_POINTS_TO_LIST_COND_FILTER pfL f2 sfL) 1312 c1) ++ 1313 DISJOINT_LIST_PRODUCT 1314 (SF_POINTS_TO_LIST_COND_FILTER pfL f2 (sfL:('c, 'b, 'a) ds_spatial_formula list))``; 1315 1316val partial_cs = reduceLib.num_compset (); 1317val _ = computeLib.add_thms [SF_POINTS_TO_LIST_def, 1318 SAFE_FILTER_THM, LIST_PRODUCT_def, DISJOINT_LIST_PRODUCT_def, pairTheory.UNCURRY_DEF, 1319 SF_POINTS_TO_LIST_COND_FILTER_def, SF_POINTS_TO_LIST_COND_THM, SWAP_REWRITES] partial_cs 1320val _ = listSimps.list_rws partial_cs; 1321 1322 1323 1324fun EVAL___DISJOINT_LIST_PRODUCT c1 pf sf f2 = 1325 let 1326 val (_, typeL) = dest_type (dest_list_type (type_of sf)) 1327 val product_term = inst [alpha |-> el 3 typeL, 1328 beta |-> el 2 typeL, 1329 gamma |-> el 1 typeL] product_term; 1330 val t = subst [mk_var("pfL",type_of pf) |-> pf, 1331 mk_var("c1",type_of c1) |-> c1, 1332 mk_var("f2",type_of f2) |-> f2, 1333 mk_var("sfL",type_of sf) |-> sf] product_term; 1334 in 1335 computeLib.CBV_CONV partial_cs t 1336 end; 1337 1338 1339fun check_unequal_is_necessary cL pfL (e1, e2) = 1340 not (isSome (find_in_list (is_uneq_2 e1 e2) pfL)) andalso 1341 ((e1 = e2) orelse 1342 not (isSome (find_entry 0 e1 cL)) orelse 1343 not (isSome (find_entry 0 e2 cL))); 1344 1345 1346 1347fun get_uneq_filter overeager cL pfL r l' [] = r | 1348 get_uneq_filter overeager cL pfL r l' ((e1,e2)::l) = 1349 let 1350 val necessary = 1351 overeager orelse ( 1352 (not (mem (e1,e2) l')) andalso 1353 (not (mem (e2,e1) l')) andalso 1354 check_unequal_is_necessary cL pfL (e1,e2)); 1355 in 1356 (get_uneq_filter overeager cL pfL (necessary::r) (if necessary then (e1,e2)::l' else l') l) 1357 end; 1358 1359 1360 1361fun ds_inference_PARTIAL___CONV___overeager over t = 1362 let 1363 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1364 val (cL, _) = strip_cons c1; 1365 val (pfL, _) = strip_cons pf; 1366 val (sfL, _) = strip_cons sf; 1367 1368 val f2L = map (get_points_to_list_cond_filter pfL) sfL; 1369 val f2 = mk_list (f2L, Type `:pointsto_cases`); 1370 1371 1372 val SF_POINTS_TO_LIST___THM = EVAL___DISJOINT_LIST_PRODUCT c1 pf sf f2; 1373 val (points_list, _) = dest_list (rhs (concl SF_POINTS_TO_LIST___THM)); 1374 val points_list = map pairLib.dest_pair points_list; 1375 1376 val pre_f = get_uneq_filter over cL pfL [] [] points_list; 1377 val (f, p) = bool_list2term___filter (rev pre_f); 1378 val _ = if p then SMALLFOOT_ERR "No new facts!" else () 1379 1380 val thm = ISPECL [f, f2, c1, c2, pf, sf, pf', sf'] INFERENCE_PARTIAL___EVAL 1381 val thm2 = CONV_RULE (RHS_CONV (REWRITE_CONV [SF_POINTS_TO_LIST___THM])) thm; 1382 val thm3 = CONV_RULE (RHS_CONV (computeLib.CBV_CONV partial_cs)) thm2; 1383 in 1384 thm3 1385 end; 1386 1387 1388val ds_inference_PARTIAL___CONV = ds_inference_PARTIAL___CONV___overeager false; 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398(*example 1399val t = ``LIST_DS_ENTAILS ([e1;e2],[(e2,e3);(e3,e4);(e4,e2);(e9,e10);(e4,e2);(e9,e10)]) ([pf_unequal e3 e4;pf1;pf_unequal e2 e4; pf3],[sf1;sf_ls "f" e1 e2;sf2]) ([],[])`` 1400*) 1401 1402fun find_strengthen_uneq_pairs___helper accu n1 n2 pfLorg [] pfL = accu 1403 | find_strengthen_uneq_pairs___helper accu n1 n2 pfLorg ((e1,e2)::cL) [] = 1404 find_strengthen_uneq_pairs___helper accu (n1+1) 0 pfLorg cL pfLorg 1405 | find_strengthen_uneq_pairs___helper accu n1 n2 pfLorg ((e1,e2)::cL) (pf::pfL) = 1406 let val accu' = (let 1407 val (e1', e2') = dest_pf_unequal pf; 1408 in 1409 if ((e1 = e1') andalso (e2 = e2')) then (n1,n2,false,e1,e2)::accu else 1410 if ((e2 = e1') andalso (e1 = e2')) then (n1,n2,true,e1,e2)::accu else 1411 accu 1412 end handle _ => accu) in 1413 find_strengthen_uneq_pairs___helper accu' n1 (n2+1) pfLorg ((e1,e2)::cL) pfL 1414 end; 1415 1416fun find_strengthen_uneq_pairs cL pfL = 1417 find_strengthen_uneq_pairs___helper [] 0 0 pfL cL pfL; 1418 1419val strengthen_cs = reduceLib.num_compset (); 1420val _ = computeLib.add_thms [SWAP_REWRITES] strengthen_cs; 1421 1422 1423fun ds_inference_PRECONDITION_STRENGTHEN___SINGLE_CONV (n1,n2,turn,e1,e2) t = 1424 let 1425 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1426 1427 val inf = if turn then INFERENCE___precondition_STRENGTHEN_2 else 1428 INFERENCE___precondition_STRENGTHEN_1; 1429 1430 val thm = ISPECL [numLib.term_of_int n2, numLib.term_of_int n1, e1, e2, c1, c2, pf, sf, pf', sf'] inf; 1431 val thm2 = CONV_RULE (computeLib.CBV_CONV strengthen_cs) thm; 1432 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No conversion"; 1433 in 1434 thm2 1435 end; 1436 1437 1438fun ds_inference_PRECONDITION_STRENGTHEN___CONV___unequal t = 1439 let 1440 val (_, c2, pf, _, _, _) = dest_LIST_DS_ENTAILS t; 1441 val (cL, _) = strip_cons c2; 1442 val cL = map pairLib.dest_pair cL; 1443 val (pfL, _) = strip_cons pf; 1444 1445 (*notice the reverse order*) 1446 val pairs_list = find_strengthen_uneq_pairs cL pfL; 1447 in 1448 EVERY_CONV (map ds_inference_PRECONDITION_STRENGTHEN___SINGLE_CONV pairs_list) t 1449 end; 1450 1451 1452 1453 1454 1455fun find_strengthen_eq_pair___helper n1 n2 pfL [] cfL = NONE 1456 | find_strengthen_eq_pair___helper n1 n2 pfL ((e1,e2)::cL) [] = 1457 find_strengthen_eq_pair___helper (n1+1) (n1+2) pfL cL (tl cL) 1458 | find_strengthen_eq_pair___helper n1 n2 pfL ((e1,e2)::cL) ((e1',e2')::cL') = 1459 let 1460 val cond = (e1 = e1') andalso (e2 = e2') andalso 1461 not (isSome (find_in_list (is_eq_2 e1 e2) pfL)) handle _ => false; 1462 in 1463 if cond then SOME (n1, n2, e1, e2) else 1464 find_strengthen_eq_pair___helper n1 (n2+1) pfL ((e1,e2)::cL) cL' 1465 end; 1466 1467fun find_strengthen_eq_pair cL pfL = 1468 valOf (find_strengthen_eq_pair___helper 0 1 pfL cL (tl cL)); 1469 1470fun ds_inference_PRECONDITION_STRENGTHEN___CONV___equal t = 1471 let 1472 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1473 val (cL, _) = strip_cons c2; 1474 val cL = map pairLib.dest_pair cL; 1475 val (pfL, _) = strip_cons pf; 1476 1477 1478 val (n1,n2,e1,e2) = find_strengthen_eq_pair cL pfL handle _ => 1479 SMALLFOOT_ERR "Not applicable"; 1480 1481 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, e1, e2, c1, c2, pf, sf, pf', sf'] 1482 INFERENCE___precondition_NOT_DISTINCT_EQ___EVAL; 1483 val thm2 = CONV_RULE (computeLib.CBV_CONV strengthen_cs) thm; 1484 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1485 in 1486 thm2 1487 end 1488 1489 1490fun find_strengthen_eq_precondition___helper n cL1 [] = NONE 1491 | find_strengthen_eq_precondition___helper n cL1 ((e1,e2)::cL2) = 1492 let 1493 val n1 = valOf (find_entry 0 e1 cL1); 1494 in 1495 SOME (n1, n, e1, e2) 1496 end handle _ => 1497 find_strengthen_eq_precondition___helper (n+1) cL1 (cL2); 1498 1499fun find_strengthen_eq_precondition cL1 cL2 = 1500 valOf (find_strengthen_eq_precondition___helper 0 cL1 cL2); 1501 1502 1503fun ds_inference_PRECONDITION_STRENGTHEN___CONV___precondition t = 1504 let 1505 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1506 val (cL1, _) = strip_cons c1; 1507 val (cL2, _) = strip_cons c2; 1508 val cL2 = map pairLib.dest_pair cL2; 1509 1510 1511 val (n1,n2,e1,e2) = find_strengthen_eq_precondition cL1 cL2 handle _ => 1512 SMALLFOOT_ERR "Not applicable"; 1513 1514 1515 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, e1, e2, c1, c2, pf, sf, pf', sf'] 1516 INFERENCE___precondition_precondition_EQ___EVAL; 1517 val thm2 = CONV_RULE (computeLib.CBV_CONV strengthen_cs) thm; 1518 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1519 in 1520 thm2 1521 end 1522 1523val ds_inference_PRECONDITION_STRENGTHEN___CONV = 1524 ds_inference_PRECONDITION_STRENGTHEN___CONV___unequal THENC 1525 (REPEATC ds_inference_PRECONDITION_STRENGTHEN___CONV___equal) THENC 1526 (REPEATC ds_inference_PRECONDITION_STRENGTHEN___CONV___precondition); 1527 1528 1529 1530(*example 1531val t = ``LIST_DS_ENTAILS ([e1],[(e2,e3);(e3,e4);(e4,e2);(e9,e10);(e4,e2);(e9,e10)]) ([pf_unequal e3 e4;pf1;pf_unequal e2 e4; pf3],[sf_ls "g" e5 e7; sf_ls "f" dse_nil e3;sf1;sf_ls "f" e1 e2;sf2]) ([],[])`` 1532*) 1533 1534val unroll_cs = reduceLib.num_compset (); 1535val _ = listSimps.list_rws unroll_cs; 1536val _ = computeLib.add_thms [SWAP_REWRITES, pairTheory.FST, listTheory.ALL_DISTINCT] unroll_cs; 1537val _ = computeLib.add_conv (``$=``, 2, stringLib.string_EQ_CONV) unroll_cs; 1538val _ = computeLib.add_conv (``$=``, 2, stringLib.char_EQ_CONV) unroll_cs; 1539 1540 1541 1542 1543 1544fun ds_inference_SIMPLE_UNROLL___CONV___list_dse_nil t = 1545 let 1546 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1547 val (sfL, _) = strip_cons sf; 1548 1549 1550 val sfOpt = find_in_list is_dse_nil_list sfL; 1551 val _ = if (isSome sfOpt) then () else SMALLFOOT_ERR "Not dse_nil list found!"; 1552 val (n, lsf) = valOf sfOpt; 1553 val (f, e1, e2) = dest_sf_ls lsf; 1554 1555 1556 val thm = ISPECL [numLib.term_of_int n, f, e2, c1, c2, pf, sf, pf', sf'] 1557 INFERENCE___NIL_LIST_EVAL 1558 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1559 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1560 in 1561 thm2 1562 end; 1563 1564 1565 1566 1567fun find_list_precond n cL [] = NONE | 1568 find_list_precond n cL (h::l) = 1569 let 1570 val (f, e1, e2) = dest_sf_ls h; 1571 val cOpt = find_entry 0 e1 cL; 1572 in 1573 if (isSome cOpt) then SOME (n, valOf cOpt, f, e1, e2) else 1574 find_list_precond (n+1) cL l 1575 end handle _ => find_list_precond (n+1) cL l; 1576 1577 1578fun ds_inference_SIMPLE_UNROLL___CONV___precondition_list t = 1579 let 1580 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1581 val (cL, _) = strip_cons c1; 1582 val (sfL, _) = strip_cons sf; 1583 1584 1585 val sfOpt = find_list_precond 0 cL sfL 1586 val _ = if (isSome sfOpt) then () else SMALLFOOT_ERR "Not suitable list found!"; 1587 val (n, m, f, e1, e2) = valOf sfOpt; 1588 1589 val thm = ISPECL [numLib.term_of_int m, numLib.term_of_int n, f, e1, e2, c1, c2, pf, sf, pf', sf'] 1590 INFERENCE___precondition_LIST_EVAL 1591 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1592 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1593 in 1594 thm2 1595 end 1596 1597 1598(* 1599val t = ``LIST_DS_ENTAILS ([e1],[(e2,e3)]) ([pf_unequal e1 e3;pf1;pf_unequal e2 e4; pf3],[sf_ls "g" e5 e7; sf_ls "f" dse_nil e3;sf_points_to e1 [("g", x); ("f", y)]; sf1;sf2]) ([],[sf432;sf_ls "f" e1 e3;sf4])`` 1600 1601val t = ``LIST_DS_ENTAILS ([e1],[(e2,e3)]) ([pf_unequal e3 e1;pf1;pf_unequal e2 e4; pf3],[sf_ls "g" e5 e7; sf_ls "f" dse_nil e3;sf_points_to e1 [("g", x); ("f", y)]; sf1;sf2]) ([],[sf_ls "f" e1 e3])`` 1602 1603val t = ``LIST_DS_ENTAILS ([e1],[(e2,e3)]) ([pf_unequal e3 e1;pf1;pf_unequal e2 e4; pf3],[sf_ls "g" e5 e7; sf_ls "f" dse_nil e3;sf_points_to e1 [("g", x); ("f", y)]; sf1;sf2]) ([],[sf_bin_tree ("f1","f2") e1])`` 1604 1605val t = ``LIST_DS_ENTAILS ([e1],[(e2,e3)]) ([pf_unequal e3 e1;pf1;pf_unequal e2 e4; pf3],[sf_ls "g" e5 e7;sf_points_to e1 [("g", x); ("f", y)]; sf1;sf2]) ([],[sf_bin_tree ("g","fa") e1])`` 1606 1607*) 1608 1609 1610fun find_list_unroll_right n sfL pfL [] = NONE | 1611 find_list_unroll_right n sfL pfL (h::l) = 1612 let 1613 val (f, e1, e3) = dest_sf_ls h; 1614 val (n3, pointer) = valOf (find_in_list (is_sf_points_to_ex e1) sfL); 1615 val (_, a, pointer_list, _) = dest_sf_points_to pointer; 1616 val e2 = snd (first (fn (x,y) => x = f) pointer_list); 1617 val (n2, uneq) = valOf (find_in_list (is_uneq_2 e1 e3) pfL); 1618 val (e1',e2') = dest_pf_unequal uneq; 1619 val turn = (e1 = e2'); 1620 in 1621 SOME (n, n2, n3, turn, e1, e2,e3, f, a) 1622 end handle _ => find_list_unroll_right (n+1) sfL pfL l; 1623 1624fun find_bin_tree_unroll_right n sfL [] = NONE | 1625 find_bin_tree_unroll_right n sfL (h::l) = 1626 let 1627 val (f1,f2, ex, _) = dest_sf_bin_tree h; 1628 val (n2, pointer) = valOf (find_in_list (is_sf_points_to_ex ex) sfL); 1629 val (_, a, pointer_list, _) = dest_sf_points_to pointer; 1630 val e1 = snd (first (fn (x,y) => x = f1) pointer_list); 1631 val e2 = snd (first (fn (x,y) => x = f2) pointer_list); 1632 in 1633 SOME (n, n2, ex, e1, e2, f1, f2, a) 1634 end handle _ => find_bin_tree_unroll_right (n+1) sfL l; 1635 1636 1637fun ds_inference_SIMPLE_UNROLL___CONV___points_to_list t = 1638 let 1639 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1640 val (pfL, _) = strip_cons pf; 1641 val (sfL, _) = strip_cons sf; 1642 val (sfL', _) = strip_cons sf'; 1643 1644 1645 val searchOpt = find_list_unroll_right 0 sfL pfL sfL'; 1646 val _ = if (isSome searchOpt) then () else SMALLFOOT_ERR "Not suitable list found!"; 1647 val (n1, n2, n3, turn, e1, e2,e3, f, a) = valOf searchOpt; 1648 1649 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, numLib.term_of_int n3, 1650 if turn then F else T, e1, e2, e3, f, a, c1, c2, pf, sf, pf', sf'] 1651 INFERENCE___NON_EMPTY_LS___EVAL 1652 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1653 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1654 in 1655 thm2 1656 end 1657 1658 1659 1660fun ds_inference_SIMPLE_UNROLL___CONV___points_to_bin_tree t = 1661 let 1662 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1663 val (sfL, _) = strip_cons sf; 1664 val (sfL', _) = strip_cons sf'; 1665 1666 1667 val searchOpt = find_bin_tree_unroll_right 0 sfL sfL'; 1668 val _ = if (isSome searchOpt) then () else SMALLFOOT_ERR "Not suitable tree found!"; 1669 val (n, n2, ex, e1, e2, f1, f2, a) = valOf searchOpt; 1670 val thm = ISPECL [numLib.term_of_int n, numLib.term_of_int n2, 1671 ex, e1, e2, f1, f2, a, c1, c2, pf, sf, pf', sf'] 1672 INFERENCE___NON_EMPTY_BIN_TREE___EVAL 1673 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1674 val _ = if (lhs (concl thm2) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1675 in 1676 thm2 1677 end 1678 1679 1680val ds_inference_SIMPLE_UNROLL___CONV = 1681 (REPEATC ds_inference_SIMPLE_UNROLL___CONV___list_dse_nil) THENC 1682 (REPEATC ds_inference_SIMPLE_UNROLL___CONV___precondition_list) THENC 1683 (REPEATC ds_inference_SIMPLE_UNROLL___CONV___points_to_list) THENC 1684 (REPEATC ds_inference_SIMPLE_UNROLL___CONV___points_to_bin_tree); 1685 1686 1687 1688 1689 1690(*example 1691val t = ``LIST_DS_ENTAILS (c1,c2) ([],[sf1;sf3;sf_bin_tree ("f1","f2") e;sf2]) ([],[])`` 1692val t = ``LIST_DS_ENTAILS (c1,c2) ([pf_unequal e1 e2],[sf1;sf3;sf_ls "f" e1 e2;sf2]) ([],[])`` 1693val t = ``LIST_DS_ENTAILS (c1,c2) ([pf2;pf_unequal e2 e1],[sf1;sf3;sf_ls "f" e1 e2;sf2]) ([],[])`` 1694 1695*) 1696 1697 1698fun prove_infinite_univ_ante thm = 1699 let 1700 val (inf_univ_t, _) = dest_imp (concl thm); 1701 val inf_univ_thm = (prove (inf_univ_t, SIMP_TAC std_ss (append (!INFINITE_UNIV___THMs) [INFINITE_UNIV___NUM,INFINITE_UNIV___STRING]))) handle _ => 1702 (let 1703 val _ = print "Could not deduce \"INFINITE UNIV\"!. It is added as an assumption.\nPlease add this theorem to INFINITE_UNIV___THMs.\n\n"; 1704 in 1705 ASSUME inf_univ_t 1706 end); 1707 in 1708 MP thm inf_univ_thm 1709 end; 1710 1711 1712fun find_list_uneq_unroll_left n pfL [] = NONE | 1713 find_list_uneq_unroll_left n pfL (h::l) = 1714 let 1715 val (f, e1, e2) = dest_sf_ls h; 1716 val (n2, uneq) = valOf (find_in_list (is_uneq_2 e1 e2) pfL); 1717 val (e1',e2') = dest_pf_unequal uneq; 1718 val turn = (e1 = e2'); 1719 in 1720 SOME (n, n2, turn, e1, e2, f) 1721 end handle _ => find_list_uneq_unroll_left (n+1) pfL l; 1722 1723 1724fun ds_inference_UNROLL_LIST___NON_EMPTY___CONV t = 1725 let 1726 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1727 val (pfL, _) = strip_cons pf; 1728 val (sfL, _) = strip_cons sf; 1729 1730 1731 val searchOpt = find_list_uneq_unroll_left 0 pfL sfL; 1732 val _ = if (isSome searchOpt) then () else SMALLFOOT_ERR "Not suitable list found!"; 1733 val (n, n2, turn, e1, e2, f) = valOf searchOpt; 1734 1735 val thm = ISPECL [numLib.term_of_int n, numLib.term_of_int n2, 1736 if turn then T else F, e1, e2, f, c1, c2, pf, sf, pf', sf'] 1737 INFERENCE_UNROLL_COLLAPSE_LS___NON_EMPTY___EVAL 1738 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1739 val thm3 = prove_infinite_univ_ante thm2; 1740 val _ = if (lhs (concl thm3) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1741 in 1742 thm3 1743 end 1744 1745val ds_inference_PRECONDITION_CASES___CONV = 1746 REWR_CONV INFERENCE_UNROLL_COLLAPSE_PRECONDITION___EVAL; 1747 1748 1749 1750fun ds_inference_UNROLL_LIST___CONV t = 1751 let 1752 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1753 val (sfL, _) = strip_cons sf; 1754 1755 1756 val searchOpt = find_in_list is_sf_ls sfL; 1757 val _ = if (isSome searchOpt) then () else SMALLFOOT_ERR "Not suitable list found!"; 1758 val (n, list_term) = valOf searchOpt; 1759 val (f, e1, e2) = dest_sf_ls list_term; 1760 1761 val thm = ISPECL [numLib.term_of_int n, 1762 e1, e2, f, c1, c2, pf, sf, pf', sf'] 1763 INFERENCE_UNROLL_COLLAPSE_LS___EVAL 1764 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1765 val thm3 = prove_infinite_univ_ante thm2; 1766 val _ = if (lhs (concl thm3) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1767 in 1768 thm3 1769 end 1770 1771 1772fun ds_inference_UNROLL_BIN_TREE___CONV t = 1773 let 1774 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1775 val (sfL, _) = strip_cons sf; 1776 1777 1778 val searchOpt = find_in_list is_sf_bin_tree sfL; 1779 val _ = if (isSome searchOpt) then () else SMALLFOOT_ERR "Not suitable binary tree found!"; 1780 val (n, tree_term) = valOf searchOpt; 1781 val (f1,f2, e1, _) = dest_sf_bin_tree tree_term; 1782 1783 val thm = ISPECL [numLib.term_of_int n, 1784 e1, f1, f2, c1, c2, pf, sf, pf', sf'] 1785 INFERENCE_UNROLL_COLLAPSE_BIN_TREE___EVAL; 1786 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1787 val thm3 = prove_infinite_univ_ante thm2; 1788 val _ = if (lhs (concl thm3) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1789 in 1790 thm3 1791 end 1792 1793 1794 1795 1796(* 1797val t = ``LIST_DS_ENTAILS (c1,c2) ([pf_equal e2 e1],[sf1;sf3;sf2]) ([],[sf_ls f e1 e2;sf_tree fL es e])`` 1798*) 1799fun is_tree_case_candidate pfL t = 1800 let 1801 val (_, e2, e1) = dest_sf_tree t; 1802 in 1803 not (isSome (find_in_list (is_uneq_2 e1 e2) pfL)) andalso 1804 not (isSome (find_in_list (is_eq_2 e1 e2) pfL)) 1805 end; 1806 1807fun ds_inference_UNROLL_RIGHT_CASES___CONV t = 1808 let 1809 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1810 val sf'' = rhs (concl (((REWRITE_CONV [sf_ls_def, sf_bin_tree_def] sf') handle _ => REFL sf'))); 1811 val (pfL, _) = strip_cons pf; 1812 val (sfL', _) = strip_cons sf''; 1813 1814 val searchOpt = find_in_list (is_tree_case_candidate pfL) sfL'; 1815 val _ = if (isSome searchOpt) then () else SMALLFOOT_ERR "Not suitable tree found!"; 1816 1817 val (n, tree_term) = valOf searchOpt; 1818 val (_, e1, e2) = dest_sf_tree tree_term; 1819 1820 val thm = ISPECL [e1, e2, c1, c2, pf, sf, pf', sf'] 1821 (GSYM INFERENCE_EXCLUDED_MIDDLE); 1822 val _ = if (lhs (concl thm) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1823 in 1824 thm 1825 end; 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836(* 1837val t = ``LIST_DS_ENTAILS ([],[]) ([pf1;pf2],[sf4;sf_ls f e1 e2; sf5;sf6]) ([],[sf2;sf_ls f e1 dse_nil;sf1])`` 1838 1839val t = ``LIST_DS_ENTAILS ([e3],[]) ([pf1;pf2;pf_unequal e3 e1],[sf4;sf_ls f e1 e2; sf5;sf6]) ([],[sf2;sf_ls f e1 e3;sf1])`` 1840 1841 1842val t = ``LIST_DS_ENTAILS ([],[]) ([pf1;pf2;pf_unequal e3 e1],[sf_points_to e3 [(f,e2)];sf4;sf_ls f e1 e2; sf5;sf6]) ([],[sf2;sf_ls f e1 e3;sf1])`` 1843 1844 1845val t = ``LIST_DS_ENTAILS ([],[]) ([pf1;pf_unequal e2 e3;pf2;pf_unequal e3 e1],[sf_points_to e3 [(f,e2)];sf4;sf_ls f e1 e2; sf5;sf_ls g e3 e2;sf6]) ([],[sf2;sf_ls f e1 e3;sf1])`` 1846 1847*) 1848 1849 1850 1851fun get_uneq_index_turn pfL e1 e3 = let 1852 val (n, pf) = valOf (find_in_list (is_uneq_2 e1 e3) pfL); 1853 val (e1', e3') = dest_pf_unequal pf; 1854 val turn = not (e1' = e1); 1855 in 1856 (n, turn) 1857 end; 1858 1859fun find_list_append_instance_nil n1 n2 e1 e2 e3 f = 1860 let 1861 val _ = if (is_dse_nil e3) then () else SMALLFOOT_ERR "Not applicable!"; 1862 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, e1, e2, f] INFERENCE_APPEND_LIST___nil___EVAL 1863 in 1864 thm 1865 end; 1866 1867fun find_list_append_instance_precond n1 n2 e1 e2 e3 f n3 b1 c1L = 1868 let 1869 val n4 = valOf (find_entry 0 e3 c1L) 1870 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, e1, e2, f, e3, numLib.term_of_int n4, numLib.term_of_int n3, if b1 then T else F] INFERENCE_APPEND_LIST___precond___EVAL 1871 in 1872 thm 1873 end; 1874 1875 1876fun find_list_append_instance_points_to n1 n2 e1 e2 e3 f n3 b1 sfL = 1877 let 1878 val (n4, pt) = valOf (find_in_list (is_sf_points_to_ex e3) sfL); 1879 val (_, a, _, _) = dest_sf_points_to pt; 1880 1881 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, e1, e2, f, e3, numLib.term_of_int n4, a, numLib.term_of_int n3, if b1 then T else F] INFERENCE_APPEND_LIST___points_to___EVAL 1882 in 1883 thm 1884 end; 1885 1886 1887fun del_el l n = 1888 List.take(l, n) @ List.drop(l, n+1) 1889 1890 1891fun find_list_append_instance_tree n1 n2 e1 e2 e3 f n3 b1 pfL sfL = 1892 let 1893 fun pred sf = 1894 let 1895 val (_, (fL, l), es, e3') = dest_sf_tree_ext sf; 1896 val _ = if (e3 = e3') then () else raise SMALLFOOT_ERR "Not suitable!"; 1897 val fLt = list_mk_cons fL l; 1898 val (n5, b2) = get_uneq_index_turn pfL es e3'; 1899 in 1900 SOME (fLt, n5, b2, es) 1901 end; 1902 val (n4, pt, (fLt, n5, b2,es)) = valOf (find_in_list_val pred (del_el sfL n1)); 1903 val n4 = if (n4 < n1) then n4 else (n4 + 1); 1904 1905 val thm = ISPECL [numLib.term_of_int n1, numLib.term_of_int n2, e1, e2, 1906 numLib.term_of_int n4, e3, fLt, es, 1907 numLib.term_of_int n3, if b1 then T else F, 1908 numLib.term_of_int n5, if b2 then T else F, f] INFERENCE_APPEND_LIST___tree___EVAL 1909 in 1910 thm 1911 end; 1912 1913 1914fun find_list_append_instance n2 c1L pfL sfL [] = NONE | 1915 find_list_append_instance n2 c1L pfL sfL (sf'::sfL') = 1916 let 1917 val (f, e1, e3) = dest_sf_ls sf'; 1918 val (n1, sf) = valOf (find_in_list (fn sf => (let val (f', e1', e2') = dest_sf_ls sf in (f = f') andalso (e1' = e1) end)) sfL); 1919 val (_, _, e2) = dest_sf_ls sf; 1920 val thm = find_list_append_instance_nil n1 n2 e1 e2 e3 f handle _ => 1921 let 1922 val (n3,b1) = get_uneq_index_turn pfL e1 e3; 1923 in 1924 find_list_append_instance_precond n1 n2 e1 e2 e3 f n3 b1 c1L handle _ => 1925 find_list_append_instance_points_to n1 n2 e1 e2 e3 f n3 b1 sfL handle _ => 1926 find_list_append_instance_tree n1 n2 e1 e2 e3 f n3 b1 pfL sfL 1927 end; 1928 in 1929 SOME thm 1930 end handle _ => find_list_append_instance (n2+1) c1L pfL sfL sfL'; 1931 1932 1933 1934fun ds_inference_APPEND_LIST___CONV t = 1935 let 1936 val (c1, c2, pf, sf, pf', sf') = dest_LIST_DS_ENTAILS t; 1937 val (c1L, _) = strip_cons c1; 1938 val (pfL, _) = strip_cons pf; 1939 val (sfL, _) = strip_cons sf; 1940 val (sfL', _) = strip_cons sf'; 1941 1942 val inferenceOpt = find_list_append_instance 0 c1L pfL sfL sfL'; 1943 val _ = if (isSome inferenceOpt) then () else SMALLFOOT_ERR "No suitable lists found!"; 1944 1945 val thm = ISPECL [c1, c2, pf, sf, pf', sf'] (valOf inferenceOpt); 1946 val thm2 = CONV_RULE (computeLib.CBV_CONV unroll_cs) thm; 1947 val thm3 = prove_infinite_univ_ante thm2; 1948 val _ = if (lhs (concl thm3) = t) then () else SMALLFOOT_ERR "No CONVERSION"; 1949 in 1950 thm3 1951 end 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963val ds_inference_NO_SPLIT_CONV = 1964 TRY_CONV ds_inference_SUBSTITUTION___CONV THENC 1965 TRY_CONV ds_inference_REMOVE_TRIVIAL___CONV THENC 1966 TRY_CONV ds_inference_HYPOTHESIS___CONV THENC 1967 TRY_CONV ds_inference_FRAME___CONV THENC 1968 TRY_CONV ds_inference_NIL_NOT_LVAL___CONV THENC 1969 TRY_CONV ds_inference_PARTIAL___CONV THENC 1970 (REPEATC ds_inference_APPEND_LIST___CONV) THENC 1971 TRY_CONV ds_inference_PRECONDITION_STRENGTHEN___CONV THENC 1972 (REPEATC ds_inference_SIMPLE_UNROLL___CONV) THENC 1973 TRY_CONV ds_inference_INCONSISTENT___CONV THENC 1974 TRY_CONV ds_inference_AXIOM___CONV; 1975 1976 1977val ds_inference_SPLIT_CONV = 1978 ds_inference_UNROLL_RIGHT_CASES___CONV ORELSEC 1979 ds_inference_PRECONDITION_CASES___CONV ORELSEC 1980 (CHANGED_CONV (REPEATC ds_inference_UNROLL_LIST___NON_EMPTY___CONV)) ORELSEC 1981 ds_inference_UNROLL_LIST___CONV ORELSEC 1982 ds_inference_UNROLL_BIN_TREE___CONV; 1983 1984 1985fun ds_inference_CHECK_LIST_DS_ENTAILS_CONV t = 1986 let 1987 val _ = dest_LIST_DS_ENTAILS t; 1988 in 1989 raise UNCHANGED 1990 end 1991 1992val ds_DECIDE_CONV = 1993 (REDEPTH_CONV (CHANGED_CONV ( 1994 ds_inference_CHECK_LIST_DS_ENTAILS_CONV THENC 1995 (REPEATC ds_inference_NO_SPLIT_CONV) THENC 1996 TRY_CONV ds_inference_SPLIT_CONV) 1997 )) THENC REWRITE_CONV[]; 1998 1999 2000fun ds_DECIDE t = EQT_ELIM (ds_DECIDE_CONV t); 2001 2002 2003 2004end; 2005