1219820Sjeffstructure tuerk_tacticsLib :> tuerk_tacticsLib = 2219820Sjeffstruct 3219820Sjeff 4219820Sjeff 5219820Sjeff open HolKernel boolLib bossLib Abbrev metisLib pred_setTheory numLib schneiderUtils 6219820Sjeff 7219820Sjeff val ERR = mk_HOL_ERR "tuerk_tacticsLib"; 8219820Sjeff 9219820Sjeff val SET_INDUCT_TAC = PSet_ind.SET_INDUCT_TAC FINITE_INDUCT; 10219820Sjeff 11219820Sjeff val EXISTS_EQ_STRIP_TAC :tactic = fn (asl,t) => 12219820Sjeff 13219820Sjeff let val (lhs,rhs) = dest_eq t 14219820Sjeff val (lvar,LBody) = dest_exists lhs 15219820Sjeff val (rvar,RBody) = dest_exists rhs 16219820Sjeff val newVar = variant (free_varsl (t::asl)) lvar 17219820Sjeff val newLBody = subst[lvar |-> newVar] LBody 18219820Sjeff val newRBody = subst[rvar |-> newVar] RBody 19219820Sjeff val result = mk_eq(newLBody, newRBody) 20219820Sjeff in ([(asl, result)], 21219820Sjeff fn thList => EXISTS_EQ newVar (hd(thList))) 22219820Sjeff end 23219820Sjeff handle HOL_ERR _ => raise ERR "EXISTS_EQ_STRIP_TAC" ""; 24219820Sjeff 25219820Sjeff 26219820Sjeff val FORALL_EQ_STRIP_TAC :tactic = fn (asl,t) => 27219820Sjeff 28219820Sjeff let val (lhs,rhs) = dest_eq t 29219820Sjeff val (lvar,LBody) = dest_forall lhs 30219820Sjeff val (rvar,RBody) = dest_forall rhs 31219820Sjeff val newVar = variant (free_varsl (t::asl)) lvar 32219820Sjeff val newLBody = subst[lvar |-> newVar] LBody 33219820Sjeff val newRBody = subst[rvar |-> newVar] RBody 34219820Sjeff val result = mk_eq(newLBody, newRBody) 35219820Sjeff in ([(asl, result)], 36219820Sjeff fn thList => FORALL_EQ newVar (hd thList)) 37219820Sjeff end 38219820Sjeff handle HOL_ERR _ => raise ERR "FORALL_EQ_STRIP_TAC" ""; 39219820Sjeff 40219820Sjeff 41219820Sjeff val REWRITE_ASSUMPTIONS_TAC = fn rwts => 42219820Sjeff POP_ASSUM_LIST (MAP_EVERY (fn thm => STRIP_ASSUME_TAC (REWRITE_RULE rwts thm))) THEN 43219820Sjeff POP_ASSUM_LIST (MAP_EVERY STRIP_ASSUME_TAC); 44219820Sjeff 45219820Sjeff 46219820Sjeff val CLEAN_ASSUMPTIONS_TAC = 47219820Sjeff REWRITE_ASSUMPTIONS_TAC[DE_MORGAN_THM, FORALL_AND_THM, EXISTS_OR_THM]; 48219820Sjeff 49219820Sjeff 50219820Sjeff val ONCE_REWRITE_ASSUMPTIONS_TAC = fn rwts => 51219820Sjeff POP_ASSUM_LIST (MAP_EVERY (fn thm => STRIP_ASSUME_TAC (ONCE_REWRITE_RULE rwts thm))) THEN 52219820Sjeff POP_ASSUM_LIST (MAP_EVERY STRIP_ASSUME_TAC); 53219820Sjeff 54219820Sjeff val REWRITE_ALL_TAC = fn rwts => 55219820Sjeff REWRITE_ASSUMPTIONS_TAC rwts THEN 56219820Sjeff REWRITE_TAC rwts; 57219820Sjeff 58219820Sjeff val ONCE_REWRITE_ALL_TAC = fn rwts => 59219820Sjeff ONCE_REWRITE_ASSUMPTIONS_TAC rwts THEN 60219820Sjeff ONCE_REWRITE_TAC rwts; 61219820Sjeff 62219820Sjeff val SIMP_ASSUMPTIONS_TAC = fn simp => fn rwts => 63219820Sjeff POP_ASSUM_LIST (MAP_EVERY (fn thm => STRIP_ASSUME_TAC (SIMP_RULE simp rwts thm))) THEN 64219820Sjeff POP_ASSUM_LIST (MAP_EVERY STRIP_ASSUME_TAC); 65219820Sjeff 66219820Sjeff val SIMP_ALL_TAC = fn simp => fn rwts => 67219820Sjeff SIMP_ASSUMPTIONS_TAC simp rwts THEN 68219820Sjeff SIMP_TAC simp rwts; 69219820Sjeff 70219820Sjeff 71219820Sjeff 72219820Sjeff fun findMatch ([], l2, c) = raise ERR "findMatch" "" | 73219820Sjeff findMatch (l1, [], c) = raise ERR "findMatch" "" | 74219820Sjeff findMatch (a::l1, b::l2, []) = findMatch (l1, b::l2, b::l2) | 75219820Sjeff findMatch (a::l1, l2, b::c) = (if (a = b) then a else findMatch (a::l1, l2, c)) 76219820Sjeff 77219820Sjeff 78219820Sjeff val DISJ_EQ_STRIP_TAC :tactic = fn (asl,t) => 79219820Sjeff let val (lhs,rhs) = dest_eq t 80219820Sjeff val l1 = strip_disj lhs 81219820Sjeff val l2 = strip_disj rhs 82219820Sjeff val m = findMatch (l1, l2, l2) 83219820Sjeff in 84219820Sjeff (DISJ_CASES_TAC (REWRITE_RULE [EQ_CLAUSES] (SPEC m BOOL_CASES_AX)) THEN ASM_REWRITE_TAC[]) (asl, t) 85219820Sjeff end 86219820Sjeff handle HOL_ERR _ => raise ERR "OR_EQ_STRIP_TAC" ""; 87219820Sjeff 88219820Sjeff 89219820Sjeff val CONJ_EQ_STRIP_TAC :tactic = fn (asl,t) => 90219820Sjeff let val (lhs,rhs) = dest_eq t 91219820Sjeff val l1 = strip_conj lhs 92219820Sjeff val l2 = strip_conj rhs 93219820Sjeff val m = findMatch (l1, l2, l2) 94219820Sjeff in 95219820Sjeff (DISJ_CASES_TAC (REWRITE_RULE [EQ_CLAUSES] (SPEC m BOOL_CASES_AX)) THEN ASM_REWRITE_TAC[]) (asl, t) 96219820Sjeff end 97219820Sjeff handle HOL_ERR _ => raise ERR "CONJ_EQ_STRIP_TAC" ""; 98219820Sjeff 99219820Sjeff val C_IMP_EQ_STRIP_TAC :tactic = fn (asl,t) => 100219820Sjeff let val (lhs,rhs) = dest_eq t 101219820Sjeff val (la, lc) = dest_imp lhs; 102219820Sjeff val (ra, rc) = dest_imp rhs; 103219820Sjeff val l1 = strip_disj lc 104219820Sjeff val l2 = strip_disj rc 105219820Sjeff val m = findMatch (l1, l2, l2) 106219820Sjeff in 107219820Sjeff (DISJ_CASES_TAC (REWRITE_RULE [EQ_CLAUSES] (SPEC m BOOL_CASES_AX)) THEN ASM_REWRITE_TAC[]) (asl, t) 108219820Sjeff end 109219820Sjeff handle HOL_ERR _ => raise ERR "IMP_EQ_STRIP_TAC" ""; 110219820Sjeff 111219820Sjeff val A_IMP_EQ_STRIP_TAC :tactic = fn (asl,t) => 112219820Sjeff let val (lhs,rhs) = dest_eq t 113219820Sjeff val (la, lc) = dest_imp lhs; 114219820Sjeff val (ra, rc) = dest_imp rhs; 115219820Sjeff val l1 = strip_conj la 116219820Sjeff val l2 = strip_conj ra 117219820Sjeff val m = findMatch (l1, l2, l2) 118219820Sjeff in 119219820Sjeff (DISJ_CASES_TAC (REWRITE_RULE [EQ_CLAUSES] (SPEC m BOOL_CASES_AX)) THEN ASM_REWRITE_TAC[]) (asl, t) 120219820Sjeff end 121219820Sjeff handle HOL_ERR _ => raise ERR "IMP_EQ_STRIP_TAC" ""; 122219820Sjeff 123219820Sjeff 124219820Sjeff val BOOL_EQ_STRIP_TAC = FIRST [DISJ_EQ_STRIP_TAC, CONJ_EQ_STRIP_TAC, 125219820Sjeff A_IMP_EQ_STRIP_TAC, C_IMP_EQ_STRIP_TAC, CHANGED_TAC (REWRITE_TAC [DE_MORGAN_THM])]; 126219820Sjeff 127219820Sjeff fun UNDISCH_KEEP_NO_TAC i = 128219820Sjeff POP_NO_ASSUM i (fn x=> (ASSUME_TAC x THEN UNDISCH_TAC (concl x) THEN ASSUME_TAC x)) 129219820Sjeff 130219820Sjeff 131219820Sjeff val UNDISCH_HD_TAC = schneiderUtils.UNDISCH_HD_TAC 132219820Sjeff val UNDISCH_ALL_TAC = schneiderUtils.UNDISCH_ALL_TAC 133219820Sjeff val UNDISCH_NO_TAC = schneiderUtils.UNDISCH_NO_TAC 134219820Sjeff val POP_NO_ASSUM = schneiderUtils.POP_NO_ASSUM 135219820Sjeff val LEFT_DISJ_TAC = schneiderUtils.LEFT_DISJ_TAC 136219820Sjeff val RIGHT_DISJ_TAC = schneiderUtils.RIGHT_DISJ_TAC 137219820Sjeff val LEFT_CONJ_TAC = schneiderUtils.LEFT_CONJ_TAC 138219820Sjeff val RIGHT_CONJ_TAC = schneiderUtils.RIGHT_CONJ_TAC 139219820Sjeff 140219820Sjeff val WEAKEN_HD_TAC = WEAKEN_TAC (fn f => true); 141219820Sjeff val WEAKEN_NO_TAC = schneiderUtils.POP_NO_TAC 142219820Sjeff val IMP_TAC = fn t => ASSUME_TAC t THEN UNDISCH_HD_TAC; 143219820Sjeff fun GSYM_NO_TAC i = POP_NO_ASSUM i (fn x=> ASSUME_TAC (GSYM x)); 144219820Sjeff 145219820Sjeff fun SUBGOAL_TAC q = Q.SUBGOAL_THEN q STRIP_ASSUME_TAC 146219820Sjeff fun REMAINS_TAC q = Tactical.REVERSE (SUBGOAL_TAC q) 147219820Sjeff val SPEC_NO_ASSUM = (fn n => fn S => POP_NO_ASSUM n (fn x=> ASSUME_TAC (SPEC S x))); 148219820Sjeff val SPECL_NO_ASSUM = (fn n => fn S => POP_NO_ASSUM n (fn x=> ASSUME_TAC (SPECL S x))); 149219820Sjeff 150219820Sjeff 151219820Sjeff fun Q_SPEC_NO_ASSUM n = Q_TAC (SPEC_NO_ASSUM n); 152219820Sjeff 153219820Sjeff fun Q_SPECL_NO_ASSUM n [] = ALL_TAC 154219820Sjeff | Q_SPECL_NO_ASSUM n (h::l) = (Q_SPEC_NO_ASSUM n h THEN Q_SPECL_NO_ASSUM 0 l); 155219820Sjeff 156219820Sjeff val IMP_TO_EQ_TAC = MATCH_MP_TAC (prove (``(a = b) ==> (a ==> b)``, SIMP_TAC std_ss [])); 157219820Sjeff 158219820Sjeff fun store_simp_thm(name,term,tac) = save_thm(name, 159219820Sjeff SIMP_RULE std_ss [] (prove(term, tac))); 160219820Sjeff 161219820Sjeff 162219820Sjeff fun EXISTS_LEAST_TAC___GEN t tac = 163219820Sjeff let 164219820Sjeff val thm = EXISTS_LEAST_CONV t; 165219820Sjeff val (lhs, rhs) = dest_eq (concl thm) 166219820Sjeff fun ASSUME_MP_TAC thm2 = ASSUME_TAC (EQ_MP thm thm2) 167219820Sjeff in 168219820Sjeff SUBGOAL_THEN lhs ASSUME_MP_TAC THEN1 tac 169219820Sjeff end; 170219820Sjeff 171219820Sjeff fun EXISTS_LEAST_TAC t = EXISTS_LEAST_TAC___GEN t (METIS_TAC[]); 172219820Sjeff val Q_EXISTS_LEAST_TAC = Q_TAC EXISTS_LEAST_TAC; 173219820Sjeff 174219820Sjeff 175219820Sjeff 176219820Sjeff fun PROVE_CONDITION_TAC thm (asl, t) = 177219820Sjeff let 178219820Sjeff val (p, c) = dest_imp (concl thm); 179219820Sjeff fun mp_thm thms = 180219820Sjeff let 181219820Sjeff val thm_p = el 1 thms; 182219820Sjeff val thm_t = el 2 thms; 183219820Sjeff val thm = MP thm thm_p; 184219820Sjeff val result = DISCH (concl thm) thm_t; 185219820Sjeff val result = MP result thm 186219820Sjeff in 187219820Sjeff result 188219820Sjeff end 189219820Sjeff in 190219820Sjeff ([(asl, p), (c::asl, t)], mp_thm) 191219820Sjeff end; 192219820Sjeff 193219820Sjeff fun PROVE_CONDITION_NO_ASSUM i = POP_NO_ASSUM i PROVE_CONDITION_TAC 194219820Sjeff 195219820Sjeff fun MATCH_LEFT_EQ_MP_TAC thm = 196219820Sjeff let 197219820Sjeff val thm = UNDISCH_ALL (SPEC_ALL thm); 198219820Sjeff val thm = fst (EQ_IMP_RULE thm); 199219820Sjeff val thm = GEN_ALL (DISCH_ALL thm) 200219820Sjeff val thm = REWRITE_RULE [AND_IMP_INTRO] thm 201219820Sjeff in 202219820Sjeff MATCH_MP_TAC thm 203219820Sjeff end 204219820Sjeff 205219820Sjeff fun MATCH_RIGHT_EQ_MP_TAC thm = 206219820Sjeff let 207219820Sjeff val thm = UNDISCH_ALL (SPEC_ALL thm); 208219820Sjeff val thm = snd (EQ_IMP_RULE thm); 209219820Sjeff val thm = GEN_ALL (DISCH_ALL thm) 210219820Sjeff val thm = REWRITE_RULE [AND_IMP_INTRO] thm 211219820Sjeff in 212219820Sjeff MATCH_MP_TAC thm 213219820Sjeff end 214219820Sjeff 215219820Sjeffend 216219820Sjeff