| author | wenzelm | 
| Wed, 02 Jan 2002 21:53:50 +0100 | |
| changeset 12618 | 43a97a2155d0 | 
| parent 12137 | 6123958975b8 | 
| child 12757 | b76a4376cfcb | 
| permissions | -rw-r--r-- | 
| 9460 | 1 | (* Title: Pure/logic.ML | 
| 0 | 2 | ID: $Id$ | 
| 9460 | 3 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | 
| 0 | 4 | Copyright Cambridge University 1992 | 
| 5 | ||
| 9460 | 6 | Abstract syntax operations of the Pure meta-logic. | 
| 0 | 7 | *) | 
| 8 | ||
| 9 | infix occs; | |
| 10 | ||
| 9460 | 11 | signature LOGIC = | 
| 4345 | 12 | sig | 
| 5041 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 13 | val is_all : term -> bool | 
| 9460 | 14 | val mk_equals : term * term -> term | 
| 15 | val dest_equals : term -> term * term | |
| 3963 
29c5ec9ecbaa
Corrected alphabetical order of entries in signature.
 nipkow parents: 
3915diff
changeset | 16 | val is_equals : term -> bool | 
| 9460 | 17 | val mk_implies : term * term -> term | 
| 18 | val dest_implies : term -> term * term | |
| 5041 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 19 | val is_implies : term -> bool | 
| 9460 | 20 | val list_implies : term list * term -> term | 
| 21 | val strip_imp_prems : term -> term list | |
| 22 | val strip_imp_concl : term -> term | |
| 23 | val strip_prems : int * term list * term -> term list * term | |
| 24 | val count_prems : term * int -> int | |
| 12137 | 25 | val mk_conjunction : term * term -> term | 
| 9460 | 26 | val mk_flexpair : term * term -> term | 
| 27 | val dest_flexpair : term -> term * term | |
| 28 | val list_flexpairs : (term*term)list * term -> term | |
| 29 | val rule_of : (term*term)list * term list * term -> term | |
| 30 | val strip_flexpairs : term -> (term*term)list * term | |
| 31 | val skip_flexpairs : term -> term | |
| 32 | val strip_horn : term -> (term*term)list * term list * term | |
| 33 | val mk_cond_defpair : term list -> term * term -> string * term | |
| 34 | val mk_defpair : term * term -> string * term | |
| 35 | val mk_type : typ -> term | |
| 36 | val dest_type : term -> typ | |
| 37 | val mk_inclass : typ * class -> term | |
| 38 | val dest_inclass : term -> typ * class | |
| 39 | val goal_const : term | |
| 40 | val mk_goal : term -> term | |
| 41 | val dest_goal : term -> term | |
| 42 | val occs : term * term -> bool | |
| 43 | val close_form : term -> term | |
| 44 | val incr_indexes : typ list * int -> term -> term | |
| 45 | val lift_fns : term * int -> (term -> term) * (term -> term) | |
| 46 | val strip_assums_hyp : term -> term list | |
| 47 | val strip_assums_concl: term -> term | |
| 48 | val strip_params : term -> (string * typ) list | |
| 10816 | 49 | val is_norm_hhf : term -> bool | 
| 9667 | 50 | val has_meta_prems : term -> int -> bool | 
| 9460 | 51 | val flatten_params : int -> term -> term | 
| 52 | val auto_rename : bool ref | |
| 53 | val set_rename_prefix : string -> unit | |
| 0 | 54 | val list_rename_params: string list * term -> term | 
| 9460 | 55 | val assum_pairs : term -> (term*term)list | 
| 56 | val varify : term -> term | |
| 57 | val unvarify : term -> term | |
| 4345 | 58 | end; | 
| 0 | 59 | |
| 1500 | 60 | structure Logic : LOGIC = | 
| 0 | 61 | struct | 
| 398 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 62 | |
| 4345 | 63 | |
| 0 | 64 | (*** Abstract syntax operations on the meta-connectives ***) | 
| 65 | ||
| 5041 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 66 | (** all **) | 
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 67 | |
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 68 | fun is_all (Const ("all", _) $ _) = true
 | 
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 69 | | is_all _ = false; | 
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 70 | |
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 71 | |
| 0 | 72 | (** equality **) | 
| 73 | ||
| 1835 | 74 | (*Make an equality. DOES NOT CHECK TYPE OF u*) | 
| 64 
0bbe5d86cb38
logic/mk_equals,mk_flexpair: now calls fastype_of instead of type_of.
 lcp parents: 
0diff
changeset | 75 | fun mk_equals(t,u) = equals(fastype_of t) $ t $ u; | 
| 0 | 76 | |
| 77 | fun dest_equals (Const("==",_) $ t $ u)  =  (t,u)
 | |
| 78 |   | dest_equals t = raise TERM("dest_equals", [t]);
 | |
| 79 | ||
| 637 | 80 | fun is_equals (Const ("==", _) $ _ $ _) = true
 | 
| 81 | | is_equals _ = false; | |
| 82 | ||
| 83 | ||
| 0 | 84 | (** implies **) | 
| 85 | ||
| 86 | fun mk_implies(A,B) = implies $ A $ B; | |
| 87 | ||
| 88 | fun dest_implies (Const("==>",_) $ A $ B)  =  (A,B)
 | |
| 89 |   | dest_implies A = raise TERM("dest_implies", [A]);
 | |
| 90 | ||
| 5041 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 91 | fun is_implies (Const ("==>", _) $ _ $ _) = true
 | 
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 92 | | is_implies _ = false; | 
| 
a1d0a6d555cd
Goals may now contain assumptions, which are not returned.
 nipkow parents: 
4822diff
changeset | 93 | |
| 4822 | 94 | |
| 0 | 95 | (** nested implications **) | 
| 96 | ||
| 97 | (* [A1,...,An], B goes to A1==>...An==>B *) | |
| 98 | fun list_implies ([], B) = B : term | |
| 99 | | list_implies (A::AS, B) = implies $ A $ list_implies(AS,B); | |
| 100 | ||
| 101 | (* A1==>...An==>B goes to [A1,...,An], where B is not an implication *) | |
| 102 | fun strip_imp_prems (Const("==>", _) $ A $ B) = A :: strip_imp_prems B
 | |
| 103 | | strip_imp_prems _ = []; | |
| 104 | ||
| 105 | (* A1==>...An==>B goes to B, where B is not an implication *) | |
| 106 | fun strip_imp_concl (Const("==>", _) $ A $ B) = strip_imp_concl B
 | |
| 107 | | strip_imp_concl A = A : term; | |
| 108 | ||
| 109 | (*Strip and return premises: (i, [], A1==>...Ai==>B) | |
| 9460 | 110 | goes to ([Ai, A(i-1),...,A1] , B) (REVERSED) | 
| 0 | 111 | if i<0 or else i too big then raises TERM*) | 
| 9460 | 112 | fun strip_prems (0, As, B) = (As, B) | 
| 113 |   | strip_prems (i, As, Const("==>", _) $ A $ B) =
 | |
| 114 | strip_prems (i-1, A::As, B) | |
| 0 | 115 |   | strip_prems (_, As, A) = raise TERM("strip_prems", A::As);
 | 
| 116 | ||
| 117 | (*Count premises -- quicker than (length ostrip_prems) *) | |
| 118 | fun count_prems (Const("==>", _) $ A $ B, n) = count_prems (B,n+1)
 | |
| 119 | | count_prems (_,n) = n; | |
| 120 | ||
| 4822 | 121 | |
| 12137 | 122 | (** conjunction **) | 
| 123 | ||
| 124 | fun mk_conjunction (t, u) = | |
| 125 |   Term.list_all ([("C", propT)], mk_implies (list_implies ([t, u], Bound 0), Bound 0));
 | |
| 126 | ||
| 127 | ||
| 128 | ||
| 0 | 129 | (** flex-flex constraints **) | 
| 130 | ||
| 64 
0bbe5d86cb38
logic/mk_equals,mk_flexpair: now calls fastype_of instead of type_of.
 lcp parents: 
0diff
changeset | 131 | (*Make a constraint.*) | 
| 
0bbe5d86cb38
logic/mk_equals,mk_flexpair: now calls fastype_of instead of type_of.
 lcp parents: 
0diff
changeset | 132 | fun mk_flexpair(t,u) = flexpair(fastype_of t) $ t $ u; | 
| 0 | 133 | |
| 134 | fun dest_flexpair (Const("=?=",_) $ t $ u)  =  (t,u)
 | |
| 135 |   | dest_flexpair t = raise TERM("dest_flexpair", [t]);
 | |
| 136 | ||
| 137 | (*make flexflex antecedents: ( [(a1,b1),...,(an,bn)] , C ) | |
| 138 | goes to (a1=?=b1) ==>...(an=?=bn)==>C *) | |
| 139 | fun list_flexpairs ([], A) = A | |
| 140 | | list_flexpairs ((t,u)::pairs, A) = | |
| 9460 | 141 | implies $ (mk_flexpair(t,u)) $ list_flexpairs(pairs,A); | 
| 0 | 142 | |
| 143 | (*Make the object-rule tpairs==>As==>B *) | |
| 144 | fun rule_of (tpairs, As, B) = list_flexpairs(tpairs, list_implies(As, B)); | |
| 145 | ||
| 9460 | 146 | (*Remove and return flexflex pairs: | 
| 147 | (a1=?=b1)==>...(an=?=bn)==>C to ( [(a1,b1),...,(an,bn)] , C ) | |
| 0 | 148 | [Tail recursive in order to return a pair of results] *) | 
| 149 | fun strip_flex_aux (pairs, Const("==>", _) $ (Const("=?=",_)$t$u) $ C) =
 | |
| 150 | strip_flex_aux ((t,u)::pairs, C) | |
| 151 | | strip_flex_aux (pairs,C) = (rev pairs, C); | |
| 152 | ||
| 153 | fun strip_flexpairs A = strip_flex_aux([], A); | |
| 154 | ||
| 155 | (*Discard flexflex pairs*) | |
| 156 | fun skip_flexpairs (Const("==>", _) $ (Const("=?=",_)$_$_) $ C) =
 | |
| 9460 | 157 | skip_flexpairs C | 
| 0 | 158 | | skip_flexpairs C = C; | 
| 159 | ||
| 9460 | 160 | (*strip a proof state (Horn clause): | 
| 0 | 161 | (a1==b1)==>...(am==bm)==>B1==>...Bn==>C | 
| 162 | goes to ( [(a1,b1),...,(am,bm)] , [B1,...,Bn] , C) *) | |
| 163 | fun strip_horn A = | |
| 9460 | 164 | let val (tpairs,horn) = strip_flexpairs A | 
| 0 | 165 | in (tpairs, strip_imp_prems horn, strip_imp_concl horn) end; | 
| 166 | ||
| 4822 | 167 | |
| 168 | (** definitions **) | |
| 169 | ||
| 170 | fun mk_cond_defpair As (lhs, rhs) = | |
| 171 | (case Term.head_of lhs of | |
| 172 | Const (name, _) => | |
| 173 | (Sign.base_name name ^ "_def", list_implies (As, mk_equals (lhs, rhs))) | |
| 174 |   | _ => raise TERM ("Malformed definition: head of lhs not a constant", [lhs, rhs]));
 | |
| 175 | ||
| 176 | fun mk_defpair lhs_rhs = mk_cond_defpair [] lhs_rhs; | |
| 177 | ||
| 178 | ||
| 398 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 179 | (** types as terms **) | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 180 | |
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 181 | fun mk_type ty = Const ("TYPE", itselfT ty);
 | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 182 | |
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 183 | fun dest_type (Const ("TYPE", Type ("itself", [ty]))) = ty
 | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 184 |   | dest_type t = raise TERM ("dest_type", [t]);
 | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 185 | |
| 4822 | 186 | |
| 447 | 187 | (** class constraints **) | 
| 398 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 188 | |
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 189 | fun mk_inclass (ty, c) = | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 190 | Const (Sign.const_of_class c, itselfT ty --> propT) $ mk_type ty; | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 191 | |
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 192 | fun dest_inclass (t as Const (c_class, _) $ ty) = | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 193 | ((dest_type ty, Sign.class_of_const c_class) | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 194 |         handle TERM _ => raise TERM ("dest_inclass", [t]))
 | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 195 |   | dest_inclass t = raise TERM ("dest_inclass", [t]);
 | 
| 
41f279b477e2
added mk_type, dest_type, mk_inclass, dest_inclass (for axclasses);
 wenzelm parents: 
210diff
changeset | 196 | |
| 0 | 197 | |
| 9460 | 198 | (** atomic goals **) | 
| 199 | ||
| 200 | val goal_const = Const ("Goal", propT --> propT);
 | |
| 201 | fun mk_goal t = goal_const $ t; | |
| 202 | ||
| 203 | fun dest_goal (Const ("Goal", _) $ t) = t
 | |
| 204 |   | dest_goal t = raise TERM ("dest_goal", [t]);
 | |
| 205 | ||
| 206 | ||
| 0 | 207 | (*** Low-level term operations ***) | 
| 208 | ||
| 209 | (*Does t occur in u? Or is alpha-convertible to u? | |
| 210 | The term t must contain no loose bound variables*) | |
| 4631 | 211 | fun t occs u = exists_subterm (fn s => t aconv s) u; | 
| 0 | 212 | |
| 213 | (*Close up a formula over all free variables by quantification*) | |
| 214 | fun close_form A = | |
| 4443 | 215 | list_all_free (sort_wrt fst (map dest_Free (term_frees A)), A); | 
| 0 | 216 | |
| 217 | ||
| 218 | (*** Specialized operations for resolution... ***) | |
| 219 | ||
| 220 | (*For all variables in the term, increment indexnames and lift over the Us | |
| 221 | result is ?Gidx(B.(lev+n-1),...,B.lev) where lev is abstraction level *) | |
| 9460 | 222 | fun incr_indexes (Us: typ list, inc:int) t = | 
| 223 | let fun incr (Var ((a,i), T), lev) = | |
| 224 | Unify.combound (Var((a, i+inc), Us---> incr_tvar inc T), | |
| 225 | lev, length Us) | |
| 226 | | incr (Abs (a,T,body), lev) = | |
| 227 | Abs (a, incr_tvar inc T, incr(body,lev+1)) | |
| 228 | | incr (Const(a,T),_) = Const(a, incr_tvar inc T) | |
| 229 | | incr (Free(a,T),_) = Free(a, incr_tvar inc T) | |
| 230 | | incr (f$t, lev) = incr(f,lev) $ incr(t,lev) | |
| 231 | | incr (t,lev) = t | |
| 0 | 232 | in incr(t,0) end; | 
| 233 | ||
| 234 | (*Make lifting functions from subgoal and increment. | |
| 235 | lift_abs operates on tpairs (unification constraints) | |
| 236 | lift_all operates on propositions *) | |
| 237 | fun lift_fns (B,inc) = | |
| 238 |   let fun lift_abs (Us, Const("==>", _) $ _ $ B) u = lift_abs (Us,B) u
 | |
| 9460 | 239 |         | lift_abs (Us, Const("all",_)$Abs(a,T,t)) u =
 | 
| 240 | Abs(a, T, lift_abs (T::Us, t) u) | |
| 241 | | lift_abs (Us, _) u = incr_indexes(rev Us, inc) u | |
| 0 | 242 |       fun lift_all (Us, Const("==>", _) $ A $ B) u =
 | 
| 9460 | 243 | implies $ A $ lift_all (Us,B) u | 
| 244 |         | lift_all (Us, Const("all",_)$Abs(a,T,t)) u =
 | |
| 245 | all T $ Abs(a, T, lift_all (T::Us,t) u) | |
| 246 | | lift_all (Us, _) u = incr_indexes(rev Us, inc) u; | |
| 0 | 247 | in (lift_abs([],B), lift_all([],B)) end; | 
| 248 | ||
| 249 | (*Strips assumptions in goal, yielding list of hypotheses. *) | |
| 250 | fun strip_assums_hyp (Const("==>", _) $ H $ B) = H :: strip_assums_hyp B
 | |
| 251 |   | strip_assums_hyp (Const("all",_)$Abs(a,T,t)) = strip_assums_hyp t
 | |
| 252 | | strip_assums_hyp B = []; | |
| 253 | ||
| 254 | (*Strips assumptions in goal, yielding conclusion. *) | |
| 255 | fun strip_assums_concl (Const("==>", _) $ H $ B) = strip_assums_concl B
 | |
| 256 |   | strip_assums_concl (Const("all",_)$Abs(a,T,t)) = strip_assums_concl t
 | |
| 257 | | strip_assums_concl B = B; | |
| 258 | ||
| 259 | (*Make a list of all the parameters in a subgoal, even if nested*) | |
| 260 | fun strip_params (Const("==>", _) $ H $ B) = strip_params B
 | |
| 261 |   | strip_params (Const("all",_)$Abs(a,T,t)) = (a,T) :: strip_params t
 | |
| 262 | | strip_params B = []; | |
| 263 | ||
| 10816 | 264 | (*test for HHF normal form*) | 
| 265 | fun is_norm_hhf (Const ("==>", _) $ _ $ (Const ("all", _) $ _)) = false
 | |
| 266 | | is_norm_hhf (t $ u) = is_norm_hhf t andalso is_norm_hhf u | |
| 267 | | is_norm_hhf (Abs (_, _, t)) = is_norm_hhf t | |
| 268 | | is_norm_hhf _ = true; | |
| 269 | ||
| 9667 | 270 | (*test for meta connectives in prems of a 'subgoal'*) | 
| 271 | fun has_meta_prems prop i = | |
| 272 | let | |
| 273 |     fun is_meta (Const ("==>", _) $ _ $ _) = true
 | |
| 10442 | 274 |       | is_meta (Const ("==", _) $ _ $ _) = true
 | 
| 9667 | 275 |       | is_meta (Const ("all", _) $ _) = true
 | 
| 276 | | is_meta _ = false; | |
| 277 | val horn = skip_flexpairs prop; | |
| 278 | in | |
| 279 | (case strip_prems (i, [], horn) of | |
| 280 | (B :: _, _) => exists is_meta (strip_assums_hyp B) | |
| 281 | | _ => false) handle TERM _ => false | |
| 282 | end; | |
| 9483 | 283 | |
| 0 | 284 | (*Removes the parameters from a subgoal and renumber bvars in hypotheses, | 
| 9460 | 285 | where j is the total number of parameters (precomputed) | 
| 0 | 286 | If n>0 then deletes assumption n. *) | 
| 9460 | 287 | fun remove_params j n A = | 
| 0 | 288 | if j=0 andalso n<=0 then A (*nothing left to do...*) | 
| 289 | else case A of | |
| 9460 | 290 |         Const("==>", _) $ H $ B =>
 | 
| 291 | if n=1 then (remove_params j (n-1) B) | |
| 292 | else implies $ (incr_boundvars j H) $ (remove_params j (n-1) B) | |
| 0 | 293 |       | Const("all",_)$Abs(a,T,t) => remove_params (j-1) n t
 | 
| 294 |       | _ => if n>0 then raise TERM("remove_params", [A])
 | |
| 295 | else A; | |
| 296 | ||
| 297 | (** Auto-renaming of parameters in subgoals **) | |
| 298 | ||
| 299 | val auto_rename = ref false | |
| 300 | and rename_prefix = ref "ka"; | |
| 301 | ||
| 302 | (*rename_prefix is not exported; it is set by this function.*) | |
| 303 | fun set_rename_prefix a = | |
| 4693 | 304 | if a<>"" andalso forall Symbol.is_letter (Symbol.explode a) | 
| 0 | 305 | then (rename_prefix := a; auto_rename := true) | 
| 306 | else error"rename prefix must be nonempty and consist of letters"; | |
| 307 | ||
| 308 | (*Makes parameters in a goal have distinctive names (not guaranteed unique!) | |
| 309 | A name clash could cause the printer to rename bound vars; | |
| 310 | then res_inst_tac would not work properly.*) | |
| 311 | fun rename_vars (a, []) = [] | |
| 312 | | rename_vars (a, (_,T)::vars) = | |
| 313 | (a,T) :: rename_vars (bump_string a, vars); | |
| 314 | ||
| 315 | (*Move all parameters to the front of the subgoal, renaming them apart; | |
| 316 | if n>0 then deletes assumption n. *) | |
| 317 | fun flatten_params n A = | |
| 318 | let val params = strip_params A; | |
| 9460 | 319 | val vars = if !auto_rename | 
| 320 | then rename_vars (!rename_prefix, params) | |
| 321 | else ListPair.zip (variantlist(map #1 params,[]), | |
| 322 | map #2 params) | |
| 0 | 323 | in list_all (vars, remove_params (length vars) n A) | 
| 324 | end; | |
| 325 | ||
| 326 | (*Makes parameters in a goal have the names supplied by the list cs.*) | |
| 327 | fun list_rename_params (cs, Const("==>", _) $ A $ B) =
 | |
| 328 | implies $ A $ list_rename_params (cs, B) | |
| 9460 | 329 |   | list_rename_params (c::cs, Const("all",_)$Abs(_,T,t)) =
 | 
| 0 | 330 | all T $ Abs(c, T, list_rename_params (cs, t)) | 
| 331 | | list_rename_params (cs, B) = B; | |
| 332 | ||
| 9684 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 333 | (*Strips assumptions in goal yielding ( [HPn,...,HP1], [xm,...,x1], B ). | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 334 | Where HPi has the form (Hi,nparams_i) and x1...xm are the parameters. | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 335 | We need nparams_i only when the parameters aren't flattened; then we | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 336 | must call incr_boundvars to make up the difference. See assum_pairs. | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 337 | Without this refinement we can get the wrong answer, e.g. by | 
| 10816 | 338 | Goal "!!f. EX B. Q(f,B) ==> (!!y. P(f,y))"; | 
| 339 | by (etac exE 1); | |
| 9684 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 340 | *) | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 341 | fun strip_assums_aux (HPs, params, Const("==>", _) $ H $ B) =
 | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 342 | strip_assums_aux ((H,length params)::HPs, params, B) | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 343 |   | strip_assums_aux (HPs, params, Const("all",_)$Abs(a,T,t)) =
 | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 344 | strip_assums_aux (HPs, (a,T)::params, t) | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 345 | | strip_assums_aux (HPs, params, B) = (HPs, params, B); | 
| 0 | 346 | |
| 347 | fun strip_assums A = strip_assums_aux ([],[],A); | |
| 348 | ||
| 349 | ||
| 350 | (*Produces disagreement pairs, one for each assumption proof, in order. | |
| 351 | A is the first premise of the lifted rule, and thus has the form | |
| 352 | H1 ==> ... Hk ==> B and the pairs are (H1,B),...,(Hk,B) *) | |
| 353 | fun assum_pairs A = | |
| 9684 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 354 | let val (HPs, params, B) = strip_assums A | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 355 | val nparams = length params | 
| 0 | 356 | val D = Unify.rlist_abs(params, B) | 
| 10816 | 357 | fun incr_hyp(H,np) = | 
| 358 | Unify.rlist_abs(params, incr_boundvars (nparams-np) H) | |
| 9460 | 359 | fun pairrev ([],pairs) = pairs | 
| 9684 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 360 | | pairrev ((H,np)::HPs, pairs) = | 
| 
6b7d7635a062
fixed strip_assums and assum_pairs, restoring them (essentially) to their
 paulson parents: 
9667diff
changeset | 361 | pairrev(HPs, (incr_hyp(H,np),D) :: pairs) | 
| 10816 | 362 | in pairrev (HPs,[]) | 
| 0 | 363 | end; | 
| 364 | ||
| 365 | (*Converts Frees to Vars and TFrees to TVars so that axioms can be written | |
| 366 | without (?) everywhere*) | |
| 367 | fun varify (Const(a,T)) = Const(a, Type.varifyT T) | |
| 368 | | varify (Free(a,T)) = Var((a,0), Type.varifyT T) | |
| 369 | | varify (Var(ixn,T)) = Var(ixn, Type.varifyT T) | |
| 370 | | varify (Abs (a,T,body)) = Abs (a, Type.varifyT T, varify body) | |
| 371 | | varify (f$t) = varify f $ varify t | |
| 372 | | varify t = t; | |
| 373 | ||
| 546 | 374 | (*Inverse of varify. Converts axioms back to their original form.*) | 
| 585 | 375 | fun unvarify (Const(a,T)) = Const(a, Type.unvarifyT T) | 
| 376 | | unvarify (Var((a,0), T)) = Free(a, Type.unvarifyT T) | |
| 377 | | unvarify (Var(ixn,T)) = Var(ixn, Type.unvarifyT T) (*non-0 index!*) | |
| 378 | | unvarify (Abs (a,T,body)) = Abs (a, Type.unvarifyT T, unvarify body) | |
| 546 | 379 | | unvarify (f$t) = unvarify f $ unvarify t | 
| 380 | | unvarify t = t; | |
| 381 | ||
| 0 | 382 | end; |