src/HOL/Import/proof_kernel.ML
changeset 24707 dfeb98f84e93
parent 24634 38db11874724
child 24712 64ed05609568
equal deleted inserted replaced
24706:c58547ff329b 24707:dfeb98f84e93
     8     type hol_type
     8     type hol_type
     9     type tag
     9     type tag
    10     type term
    10     type term
    11     type thm
    11     type thm
    12     type ('a,'b) subst
    12     type ('a,'b) subst
    13 	 
    13 
    14     type proof_info
    14     type proof_info
    15     datatype proof = Proof of proof_info * proof_content
    15     datatype proof = Proof of proof_info * proof_content
    16 	 and proof_content
    16 	 and proof_content
    17 	   = PRefl of term
    17 	   = PRefl of term
    18 	   | PInstT of proof * (hol_type,hol_type) subst
    18 	   | PInstT of proof * (hol_type,hol_type) subst
   109     val new_definition : string -> string -> term -> theory -> theory * thm
   109     val new_definition : string -> string -> term -> theory -> theory * thm
   110     val new_specification : string -> string -> string list -> thm -> theory -> theory * thm
   110     val new_specification : string -> string -> string list -> thm -> theory -> theory * thm
   111     val new_type_definition : string -> string -> string -> thm -> theory -> theory * thm
   111     val new_type_definition : string -> string -> string -> thm -> theory -> theory * thm
   112     val new_axiom : string -> term -> theory -> theory * thm
   112     val new_axiom : string -> term -> theory -> theory * thm
   113 
   113 
   114     val prin : term -> unit 
   114     val prin : term -> unit
   115     val protect_factname : string -> string 
   115     val protect_factname : string -> string
   116     val replay_protect_varname : string -> string -> unit
   116     val replay_protect_varname : string -> string -> unit
   117     val replay_add_dump : string -> theory -> theory
   117     val replay_add_dump : string -> theory -> theory
   118 end
   118 end
   119 
   119 
   120 structure ProofKernel :> ProofKernel =
   120 structure ProofKernel :> ProofKernel =
   123 type term = Term.term
   123 type term = Term.term
   124 datatype tag = Tag of string list
   124 datatype tag = Tag of string list
   125 type ('a,'b) subst = ('a * 'b) list
   125 type ('a,'b) subst = ('a * 'b) list
   126 datatype thm = HOLThm of (Term.term * Term.term) list * Thm.thm
   126 datatype thm = HOLThm of (Term.term * Term.term) list * Thm.thm
   127 
   127 
   128 fun hthm2thm (HOLThm (_, th)) = th 
   128 fun hthm2thm (HOLThm (_, th)) = th
   129 
   129 
   130 fun to_hol_thm th = HOLThm ([], th)
   130 fun to_hol_thm th = HOLThm ([], th)
   131 
   131 
   132 val replay_add_dump = add_dump
   132 val replay_add_dump = add_dump
   133 fun add_dump s thy = (ImportRecorder.add_dump s; replay_add_dump s thy)
   133 fun add_dump s thy = (ImportRecorder.add_dump s; replay_add_dump s thy)
   134 
   134 
   135 datatype proof_info
   135 datatype proof_info
   136   = Info of {disk_info: (string * string) option ref}
   136   = Info of {disk_info: (string * string) option ref}
   137 	    
   137 
   138 datatype proof = Proof of proof_info * proof_content
   138 datatype proof = Proof of proof_info * proof_content
   139      and proof_content
   139      and proof_content
   140        = PRefl of term
   140        = PRefl of term
   141        | PInstT of proof * (hol_type,hol_type) subst
   141        | PInstT of proof * (hol_type,hol_type) subst
   142        | PSubst of proof list * term * proof
   142        | PSubst of proof list * term * proof
   174        | PContr of proof * term
   174        | PContr of proof * term
   175 
   175 
   176 exception PK of string * string
   176 exception PK of string * string
   177 fun ERR f mesg = PK (f,mesg)
   177 fun ERR f mesg = PK (f,mesg)
   178 
   178 
   179 fun print_exn e = 
   179 fun print_exn e =
   180     case e of
   180     case e of
   181 	PK (m,s) => (writeln ("PK (" ^ m ^ "): " ^ s); raise e)
   181 	PK (m,s) => (writeln ("PK (" ^ m ^ "): " ^ s); raise e)
   182       | _ => OldGoals.print_exn e
   182       | _ => OldGoals.print_exn e
   183 
   183 
   184 (* Compatibility. *)
   184 (* Compatibility. *)
   211 exception SMART_STRING
   211 exception SMART_STRING
   212 
   212 
   213 fun smart_string_of_cterm ct =
   213 fun smart_string_of_cterm ct =
   214     let
   214     let
   215 	val {thy,t,T,...} = rep_cterm ct
   215 	val {thy,t,T,...} = rep_cterm ct
       
   216         val ctxt = ProofContext.init thy
   216         (* Hack to avoid parse errors with Trueprop *)
   217         (* Hack to avoid parse errors with Trueprop *)
   217 	val ct  = (cterm_of thy (HOLogic.dest_Trueprop t)
   218 	val ct  = (cterm_of thy (HOLogic.dest_Trueprop t)
   218 		   handle TERM _ => ct)
   219 		   handle TERM _ => ct)
   219 	fun match cu = t aconv (term_of cu)
   220 	fun match u = t aconv u
   220 	fun G 0 = Library.setmp show_types true (Library.setmp show_sorts true)
   221 	fun G 0 = Library.setmp show_types true (Library.setmp show_sorts true)
   221 	  | G 1 = Library.setmp show_brackets true (G 0)
   222 	  | G 1 = Library.setmp show_brackets true (G 0)
   222 	  | G 2 = Library.setmp show_all_types true (G 0)
   223 	  | G 2 = Library.setmp show_all_types true (G 0)
   223 	  | G 3 = Library.setmp show_brackets true (G 2)
   224 	  | G 3 = Library.setmp show_brackets true (G 2)
   224           | G _ = raise SMART_STRING 
   225           | G _ = raise SMART_STRING
   225 	fun F n =
   226 	fun F n =
   226 	    let
   227 	    let
   227 		val str = Library.setmp show_brackets false (G n string_of_cterm) ct
   228 		val str = Library.setmp show_brackets false (G n string_of_cterm) ct
   228 		val cu  = Thm.read_cterm thy (str,T)
   229 		val u = Syntax.parse_term ctxt str
   229 	    in
   230                   |> TypeInfer.constrain T |> Syntax.check_term ctxt
   230 		if match cu
   231 	    in
       
   232 		if match u
   231 		then quote str
   233 		then quote str
   232 		else F (n+1)
   234 		else F (n+1)
   233 	    end
   235 	    end
   234 	    handle ERROR mesg => F (n+1)
   236 	    handle ERROR mesg => F (n+1)
   235 		 | SMART_STRING => raise ERROR ("smart_string failed for: "^(G 0 string_of_cterm ct))
   237 		 | SMART_STRING => raise ERROR ("smart_string failed for: "^(G 0 string_of_cterm ct))
   236     in
   238     in
   237       PrintMode.setmp [] (Library.setmp Syntax.ambiguity_is_error true F) 0
   239       PrintMode.setmp [] (Library.setmp Syntax.ambiguity_is_error true F) 0
   238     end
   240     end
   239     handle ERROR mesg => simple_smart_string_of_cterm ct
   241     handle ERROR mesg => simple_smart_string_of_cterm ct
   240  
   242 
   241 val smart_string_of_thm = smart_string_of_cterm o cprop_of
   243 val smart_string_of_thm = smart_string_of_cterm o cprop_of
   242 
   244 
   243 fun prth th = writeln (PrintMode.setmp [] string_of_thm th)
   245 fun prth th = writeln (PrintMode.setmp [] string_of_thm th)
   244 fun prc ct = writeln (PrintMode.setmp [] string_of_cterm ct)
   246 fun prc ct = writeln (PrintMode.setmp [] string_of_cterm ct)
   245 fun prin t = writeln (PrintMode.setmp [] (fn () => Sign.string_of_term (the_context ()) t) ());
   247 fun prin t = writeln (PrintMode.setmp [] (fn () => Sign.string_of_term (the_context ()) t) ());
   270 			       then y
   272 			       then y
   271 			       else F rest
   273 			       else F rest
   272     in
   274     in
   273 	F
   275 	F
   274     end
   276     end
   275 fun i mem L = 
   277 fun i mem L =
   276     let fun itr [] = false 
   278     let fun itr [] = false
   277 	  | itr (a::rst) = i=a orelse itr rst 
   279 	  | itr (a::rst) = i=a orelse itr rst
   278     in itr L end;
   280     in itr L end;
   279     
   281 
   280 fun insert i L = if i mem L then L else i::L
   282 fun insert i L = if i mem L then L else i::L
   281 					
   283 
   282 fun mk_set [] = []
   284 fun mk_set [] = []
   283   | mk_set (a::rst) = insert a (mk_set rst)
   285   | mk_set (a::rst) = insert a (mk_set rst)
   284 		      
   286 
   285 fun [] union S = S
   287 fun [] union S = S
   286   | S union [] = S
   288   | S union [] = S
   287   | (a::rst) union S2 = rst union (insert a S2)
   289   | (a::rst) union S2 = rst union (insert a S2)
   288 			
   290 
   289 fun implode_subst [] = []
   291 fun implode_subst [] = []
   290   | implode_subst (x::r::rest) = ((x,r)::(implode_subst rest))
   292   | implode_subst (x::r::rest) = ((x,r)::(implode_subst rest))
   291   | implode_subst _ = raise ERR "implode_subst" "malformed substitution list"
   293   | implode_subst _ = raise ERR "implode_subst" "malformed substitution list"
   292 
   294 
   293 end
   295 end
   298 val empty_tag = Tag []
   300 val empty_tag = Tag []
   299 fun read name = Tag [name]
   301 fun read name = Tag [name]
   300 fun merge (Tag tag1) (Tag tag2) = Tag (Lib.union(tag1,tag2))
   302 fun merge (Tag tag1) (Tag tag2) = Tag (Lib.union(tag1,tag2))
   301 end
   303 end
   302 
   304 
   303 (* Acutal code. *)
   305 (* Actual code. *)
   304 
   306 
   305 fun get_segment thyname l = (Lib.assoc "s" l
   307 fun get_segment thyname l = (Lib.assoc "s" l
   306 			     handle PK _ => thyname)
   308 			     handle PK _ => thyname)
   307 val get_name : (string * string) list -> string = Lib.assoc "n"
   309 val get_name : (string * string) list -> string = Lib.assoc "n"
   308 
   310 
   428 fun dom_rng (Type("fun",[dom,rng])) = (dom,rng)
   430 fun dom_rng (Type("fun",[dom,rng])) = (dom,rng)
   429   | dom_rng _ = raise ERR "dom_rng" "Not a functional type"
   431   | dom_rng _ = raise ERR "dom_rng" "Not a functional type"
   430 
   432 
   431 fun mk_thy_const thy Thy Nam Ty = Const(intern_const_name Thy Nam thy,Ty)
   433 fun mk_thy_const thy Thy Nam Ty = Const(intern_const_name Thy Nam thy,Ty)
   432 
   434 
   433 local 
   435 local
   434   fun get_const sg thyname name = 
   436   fun get_const sg thyname name =
   435     (case Sign.const_type sg name of
   437     (case Sign.const_type sg name of
   436       SOME ty => Const (name, ty)
   438       SOME ty => Const (name, ty)
   437     | NONE => raise ERR "get_type" (name ^ ": No such constant"))
   439     | NONE => raise ERR "get_type" (name ^ ": No such constant"))
   438 in
   440 in
   439 fun prim_mk_const thy Thy Nam =
   441 fun prim_mk_const thy Thy Nam =
   470 fun innocent_varname s = Syntax.is_identifier s andalso not (String.isPrefix "u_" s)
   472 fun innocent_varname s = Syntax.is_identifier s andalso not (String.isPrefix "u_" s)
   471 
   473 
   472 val check_name_thy = theory "Main"
   474 val check_name_thy = theory "Main"
   473 
   475 
   474 fun valid_boundvarname s =
   476 fun valid_boundvarname s =
   475   can (fn () => Thm.read_cterm check_name_thy ("SOME "^s^". True", dummyT)) ();
   477   can (fn () => Syntax.read_term_global check_name_thy ("SOME "^s^". True")) ();
   476 
   478 
   477 fun valid_varname s =
   479 fun valid_varname s =
   478   can (fn () => Thm.read_cterm check_name_thy (s, dummyT)) ();
   480   can (fn () => Syntax.read_term_global check_name_thy s) ();
   479 
   481 
   480 fun protect_varname s =
   482 fun protect_varname s =
   481     if innocent_varname s andalso valid_varname s then s else
   483     if innocent_varname s andalso valid_varname s then s else
   482     case Symtab.lookup (!protected_varnames) s of
   484     case Symtab.lookup (!protected_varnames) s of
   483       SOME t => t
   485       SOME t => t
   484     | NONE => 
   486     | NONE =>
   485       let
   487       let
   486 	  val _ = inc invented_isavar
   488 	  val _ = inc invented_isavar
   487 	  val t = "u_" ^ string_of_int (!invented_isavar)
   489 	  val t = "u_" ^ string_of_int (!invented_isavar)
   488 	  val _ = ImportRecorder.protect_varname s t
   490 	  val _ = ImportRecorder.protect_varname s t
   489           val _ = protected_varnames := Symtab.update (s, t) (!protected_varnames)
   491           val _ = protected_varnames := Symtab.update (s, t) (!protected_varnames)
   491 	  t
   493 	  t
   492       end
   494       end
   493 
   495 
   494 exception REPLAY_PROTECT_VARNAME of string*string*string
   496 exception REPLAY_PROTECT_VARNAME of string*string*string
   495 
   497 
   496 fun replay_protect_varname s t = 
   498 fun replay_protect_varname s t =
   497 	case Symtab.lookup (!protected_varnames) s of
   499 	case Symtab.lookup (!protected_varnames) s of
   498 	  SOME t' => raise REPLAY_PROTECT_VARNAME (s, t, t')
   500 	  SOME t' => raise REPLAY_PROTECT_VARNAME (s, t, t')
   499 	| NONE => 	
   501 	| NONE =>
   500           let
   502           let
   501 	      val _ = inc invented_isavar
   503 	      val _ = inc invented_isavar
   502 	      val t = "u_" ^ string_of_int (!invented_isavar)
   504 	      val t = "u_" ^ string_of_int (!invented_isavar)
   503               val _ = protected_varnames := Symtab.update (s, t) (!protected_varnames)
   505               val _ = protected_varnames := Symtab.update (s, t) (!protected_varnames)
   504           in
   506           in
   505 	      ()
   507 	      ()
   506           end	       	
   508           end
   507 	 
   509 
   508 fun protect_boundvarname s = if innocent_varname s andalso valid_boundvarname s then s else "u"
   510 fun protect_boundvarname s = if innocent_varname s andalso valid_boundvarname s then s else "u"
   509 
   511 
   510 fun mk_lambda (v as Free (x, T)) t = Abs (protect_boundvarname x, T, abstract_over (v, t))
   512 fun mk_lambda (v as Free (x, T)) t = Abs (protect_boundvarname x, T, abstract_over (v, t))
   511   | mk_lambda (v as Var ((x, _), T)) t = Abs (protect_boundvarname x, T, abstract_over (v, t))
   513   | mk_lambda (v as Var ((x, _), T)) t = Abs (protect_boundvarname x, T, abstract_over (v, t))
   512   | mk_lambda v t = raise TERM ("lambda", [v, t]);
   514   | mk_lambda v t = raise TERM ("lambda", [v, t]);
   513  
   515 
   514 fun replacestr x y s = 
   516 fun replacestr x y s =
   515 let
   517 let
   516   val xl = explode x
   518   val xl = explode x
   517   val yl = explode y
   519   val yl = explode y
   518   fun isprefix [] ys = true
   520   fun isprefix [] ys = true
   519     | isprefix (x::xs) (y::ys) = if x = y then isprefix xs ys else false
   521     | isprefix (x::xs) (y::ys) = if x = y then isprefix xs ys else false
   520     | isprefix _ _ = false  
   522     | isprefix _ _ = false
   521   fun isp s = isprefix xl s
   523   fun isp s = isprefix xl s
   522   fun chg s = yl@(List.drop (s, List.length xl))
   524   fun chg s = yl@(List.drop (s, List.length xl))
   523   fun r [] = []
   525   fun r [] = []
   524     | r (S as (s::ss)) = if isp S then r (chg S) else s::(r ss) 
   526     | r (S as (s::ss)) = if isp S then r (chg S) else s::(r ss)
   525 in
   527 in
   526   implode(r (explode s))
   528   implode(r (explode s))
   527 end    
   529 end
   528 
   530 
   529 fun protect_factname s = replacestr "." "_dot_" s
   531 fun protect_factname s = replacestr "." "_dot_" s
   530 fun unprotect_factname s = replacestr "_dot_" "." s 
   532 fun unprotect_factname s = replacestr "_dot_" "." s
   531 
   533 
   532 val ty_num_prefix = "N_"
   534 val ty_num_prefix = "N_"
   533 
   535 
   534 fun startsWithDigit s = Char.isDigit (hd (String.explode s))
   536 fun startsWithDigit s = Char.isDigit (hd (String.explode s))
   535 
   537 
   536 fun protect_tyname tyn = 
   538 fun protect_tyname tyn =
   537   let
   539   let
   538     val tyn' = 
   540     val tyn' =
   539       if String.isPrefix ty_num_prefix tyn then raise (ERR "protect_ty_name" ("type name '"^tyn^"' is reserved")) else 
   541       if String.isPrefix ty_num_prefix tyn then raise (ERR "protect_ty_name" ("type name '"^tyn^"' is reserved")) else
   540       (if startsWithDigit tyn then ty_num_prefix^tyn else tyn)
   542       (if startsWithDigit tyn then ty_num_prefix^tyn else tyn)
   541   in
   543   in
   542     tyn'
   544     tyn'
   543   end
   545   end
   544 
   546 
   545 fun protect_constname tcn = tcn 
   547 fun protect_constname tcn = tcn
   546  (* if tcn = ".." then "dotdot"
   548  (* if tcn = ".." then "dotdot"
   547   else if tcn = "==" then "eqeq"
   549   else if tcn = "==" then "eqeq"
   548   else tcn*)
   550   else tcn*)
   549 
   551 
   550 structure TypeNet =
   552 structure TypeNet =
   632 		val f = get_term_from_index thy thyname types terms tmf
   634 		val f = get_term_from_index thy thyname types terms tmf
   633 		val a = get_term_from_index thy thyname types terms tma
   635 		val a = get_term_from_index thy thyname types terms tma
   634 	    in
   636 	    in
   635 		mk_comb(f,a)
   637 		mk_comb(f,a)
   636 	    end
   638 	    end
   637 	  | gtfx (Elem("tml",[("x",tmx),("a",tma)],[])) = 
   639 	  | gtfx (Elem("tml",[("x",tmx),("a",tma)],[])) =
   638 	    let		
   640 	    let
   639                 val x = get_term_from_index thy thyname types terms tmx 
   641                 val x = get_term_from_index thy thyname types terms tmx
   640                 val a = get_term_from_index thy thyname types terms tma
   642                 val a = get_term_from_index thy thyname types terms tma
   641 	    in
   643 	    in
   642 		mk_lambda x a
   644 		mk_lambda x a
   643 	    end
   645 	    end
   644 	  | gtfx (Elem("tmi",[("i",iS)],[])) =
   646 	  | gtfx (Elem("tmi",[("i",iS)],[])) =
   681 		 else find ps
   683 		 else find ps
   682 	     end) handle OS.SysErr _ => find ps
   684 	     end) handle OS.SysErr _ => find ps
   683     in
   685     in
   684 	Option.map (fn p => OS.Path.joinDirFile {dir = p, file = thyname}) (find path)
   686 	Option.map (fn p => OS.Path.joinDirFile {dir = p, file = thyname}) (find path)
   685     end
   687     end
   686 			   
   688 
   687 fun proof_file_name thyname thmname thy =
   689 fun proof_file_name thyname thmname thy =
   688     let
   690     let
   689 	val path = case get_proof_dir thyname thy of
   691 	val path = case get_proof_dir thyname thy of
   690 		       SOME p => p
   692 		       SOME p => p
   691 		     | NONE => error "Cannot find proof files"
   693 		     | NONE => error "Cannot find proof files"
   692 	val _ = OS.FileSys.mkDir path handle OS.SysErr _ => ()
   694 	val _ = OS.FileSys.mkDir path handle OS.SysErr _ => ()
   693     in
   695     in
   694 	OS.Path.joinDirFile {dir = path, file = OS.Path.joinBaseExt {base = (unprotect_factname thmname), ext = SOME "prf"}}
   696 	OS.Path.joinDirFile {dir = path, file = OS.Path.joinBaseExt {base = (unprotect_factname thmname), ext = SOME "prf"}}
   695     end
   697     end
   696 	
   698 
   697 fun xml_to_proof thyname types terms prf thy =
   699 fun xml_to_proof thyname types terms prf thy =
   698     let
   700     let
   699 	val xml_to_hol_type = TypeNet.get_type_from_xml thy thyname types
   701 	val xml_to_hol_type = TypeNet.get_type_from_xml thy thyname types
   700 	val xml_to_term = TermNet.get_term_from_xml thy thyname types terms
   702 	val xml_to_term = TermNet.get_term_from_xml thy thyname types terms
   701 
   703 
   934 	  | x2p xml = raise ERR "x2p" "Bad proof"
   936 	  | x2p xml = raise ERR "x2p" "Bad proof"
   935     in
   937     in
   936 	x2p prf
   938 	x2p prf
   937     end
   939     end
   938 
   940 
   939 fun import_proof_concl thyname thmname thy = 
   941 fun import_proof_concl thyname thmname thy =
   940     let
   942     let
   941 	val is = TextIO.openIn(proof_file_name thyname thmname thy)
   943 	val is = TextIO.openIn(proof_file_name thyname thmname thy)
   942 	val (proof_xml,_) = scan_tag (LazySeq.of_instream is)
   944 	val (proof_xml,_) = scan_tag (LazySeq.of_instream is)
   943 	val _ = TextIO.closeIn is
   945 	val _ = TextIO.closeIn is
   944     in 
   946     in
   945 	case proof_xml of
   947 	case proof_xml of
   946 	    Elem("proof",[],xtypes::xterms::prf::rest) =>
   948 	    Elem("proof",[],xtypes::xterms::prf::rest) =>
   947 	    let
   949 	    let
   948 		val types = TypeNet.input_types thyname xtypes
   950 		val types = TypeNet.input_types thyname xtypes
   949 		val terms = TermNet.input_terms thyname types xterms
   951 		val terms = TermNet.input_terms thyname types xterms
   950                 fun f xtm thy = TermNet.get_term_from_xml thy thyname types terms xtm               
   952                 fun f xtm thy = TermNet.get_term_from_xml thy thyname types terms xtm
   951 	    in
   953 	    in
   952 		case rest of
   954 		case rest of
   953 		    [] => NONE
   955 		    [] => NONE
   954 		  | [xtm] => SOME (f xtm)
   956 		  | [xtm] => SOME (f xtm)
   955 		  | _ => raise ERR "import_proof" "Bad argument list"
   957 		  | _ => raise ERR "import_proof" "Bad argument list"
   960 fun import_proof thyname thmname thy =
   962 fun import_proof thyname thmname thy =
   961     let
   963     let
   962 	val is = TextIO.openIn(proof_file_name thyname thmname thy)
   964 	val is = TextIO.openIn(proof_file_name thyname thmname thy)
   963 	val (proof_xml,_) = scan_tag (LazySeq.of_instream is)
   965 	val (proof_xml,_) = scan_tag (LazySeq.of_instream is)
   964 	val _ = TextIO.closeIn is
   966 	val _ = TextIO.closeIn is
   965     in 
   967     in
   966 	case proof_xml of
   968 	case proof_xml of
   967 	    Elem("proof",[],xtypes::xterms::prf::rest) =>
   969 	    Elem("proof",[],xtypes::xterms::prf::rest) =>
   968 	    let
   970 	    let
   969 		val types = TypeNet.input_types thyname xtypes
   971 		val types = TypeNet.input_types thyname xtypes
   970 		val terms = TermNet.input_terms thyname types xterms
   972 		val terms = TermNet.input_terms thyname types xterms
  1066 	val res = implies_intr_hyps th4
  1068 	val res = implies_intr_hyps th4
  1067     in
  1069     in
  1068 	res
  1070 	res
  1069     end
  1071     end
  1070 
  1072 
  1071 val permute_prems = Thm.permute_prems 
  1073 val permute_prems = Thm.permute_prems
  1072 
  1074 
  1073 fun rearrange sg tm th =
  1075 fun rearrange sg tm th =
  1074     let
  1076     let
  1075 	val tm' = Envir.beta_eta_contract tm
  1077 	val tm' = Envir.beta_eta_contract tm
  1076 	fun find []      n = permute_prems 0 1 (implies_intr (Thm.cterm_of sg tm) th)
  1078 	fun find []      n = permute_prems 0 1 (implies_intr (Thm.cterm_of sg tm) th)
  1150       fun is_old_name n = n mem_string freenames
  1152       fun is_old_name n = n mem_string freenames
  1151       fun name_of (Free (n, _)) = n
  1153       fun name_of (Free (n, _)) = n
  1152         | name_of _ = ERR "name_of"
  1154         | name_of _ = ERR "name_of"
  1153       fun new_name' bump map n =
  1155       fun new_name' bump map n =
  1154           let val n' = n^bump in
  1156           let val n' = n^bump in
  1155             if is_old_name n' orelse Symtab.lookup map n' <> NONE then 
  1157             if is_old_name n' orelse Symtab.lookup map n' <> NONE then
  1156               new_name' (Symbol.bump_string bump) map n
  1158               new_name' (Symbol.bump_string bump) map n
  1157             else
  1159             else
  1158               n'
  1160               n'
  1159           end              
  1161           end
  1160       val new_name = new_name' "a"
  1162       val new_name = new_name' "a"
  1161       fun replace_name n' (Free (n, t)) = Free (n', t)
  1163       fun replace_name n' (Free (n, t)) = Free (n', t)
  1162         | replace_name n' _ = ERR "replace_name"
  1164         | replace_name n' _ = ERR "replace_name"
  1163       (* map: old or fresh name -> old free, 
  1165       (* map: old or fresh name -> old free,
  1164          invmap: old free which has fresh name assigned to it -> fresh name *)
  1166          invmap: old free which has fresh name assigned to it -> fresh name *)
  1165       fun dis (v, mapping as (map,invmap)) =
  1167       fun dis (v, mapping as (map,invmap)) =
  1166           let val n = name_of v in
  1168           let val n = name_of v in
  1167             case Symtab.lookup map n of
  1169             case Symtab.lookup map n of
  1168               NONE => (Symtab.update (n, v) map, invmap)
  1170               NONE => (Symtab.update (n, v) map, invmap)
  1169             | SOME v' => 
  1171             | SOME v' =>
  1170               if v=v' then 
  1172               if v=v' then
  1171                 mapping 
  1173                 mapping
  1172               else
  1174               else
  1173                 let val n' = new_name map n in
  1175                 let val n' = new_name map n in
  1174                   (Symtab.update (n', v) map, 
  1176                   (Symtab.update (n', v) map,
  1175                    Termtab.update (v, n') invmap)
  1177                    Termtab.update (v, n') invmap)
  1176                 end
  1178                 end
  1177           end
  1179           end
  1178     in
  1180     in
  1179       if (length freenames = length frees) then
  1181       if (length freenames = length frees) then
  1180         thm
  1182         thm
  1181       else
  1183       else
  1182         let 
  1184         let
  1183           val (_, invmap) = 
  1185           val (_, invmap) =
  1184               List.foldl dis (Symtab.empty, Termtab.empty) frees 
  1186               List.foldl dis (Symtab.empty, Termtab.empty) frees
  1185           fun make_subst ((oldfree, newname), (intros, elims)) =
  1187           fun make_subst ((oldfree, newname), (intros, elims)) =
  1186               (cterm_of thy oldfree :: intros, 
  1188               (cterm_of thy oldfree :: intros,
  1187                cterm_of thy (replace_name newname oldfree) :: elims)
  1189                cterm_of thy (replace_name newname oldfree) :: elims)
  1188           val (intros, elims) = List.foldl make_subst ([], []) (Termtab.dest invmap)
  1190           val (intros, elims) = List.foldl make_subst ([], []) (Termtab.dest invmap)
  1189         in 
  1191         in
  1190           forall_elim_list elims (forall_intr_list intros thm)
  1192           forall_elim_list elims (forall_intr_list intros thm)
  1191         end     
  1193         end
  1192     end
  1194     end
  1193 
  1195 
  1194 val debug = ref false
  1196 val debug = ref false
  1195 
  1197 
  1196 fun if_debug f x = if !debug then f x else ()
  1198 fun if_debug f x = if !debug then f x else ()
  1199 val conjE_helper = permute_prems 0 1 conjE
  1201 val conjE_helper = permute_prems 0 1 conjE
  1200 
  1202 
  1201 fun get_hol4_thm thyname thmname thy =
  1203 fun get_hol4_thm thyname thmname thy =
  1202     case get_hol4_theorem thyname thmname thy of
  1204     case get_hol4_theorem thyname thmname thy of
  1203 	SOME hth => SOME (HOLThm hth)
  1205 	SOME hth => SOME (HOLThm hth)
  1204       | NONE => 
  1206       | NONE =>
  1205 	let
  1207 	let
  1206 	    val pending = HOL4Pending.get thy
  1208 	    val pending = HOL4Pending.get thy
  1207 	in
  1209 	in
  1208 	    case StringPair.lookup pending (thyname,thmname) of
  1210 	    case StringPair.lookup pending (thyname,thmname) of
  1209 		SOME hth => SOME (HOLThm hth)
  1211 		SOME hth => SOME (HOLThm hth)
  1213 fun non_trivial_term_consts tm =
  1215 fun non_trivial_term_consts tm =
  1214     List.filter (fn c => not (c = "Trueprop" orelse
  1216     List.filter (fn c => not (c = "Trueprop" orelse
  1215 			 c = "All" orelse
  1217 			 c = "All" orelse
  1216 			 c = "op -->" orelse
  1218 			 c = "op -->" orelse
  1217 			 c = "op &" orelse
  1219 			 c = "op &" orelse
  1218 			 c = "op =")) (Term.term_consts tm) 
  1220 			 c = "op =")) (Term.term_consts tm)
  1219 
  1221 
  1220 fun match_consts t (* th *) =
  1222 fun match_consts t (* th *) =
  1221     let
  1223     let
  1222 	fun add_consts (Const (c, _), cs) =
  1224 	fun add_consts (Const (c, _), cs) =
  1223 	    (case c of
  1225 	    (case c of
  1289 		       | NONE => (message "NO2";error "get_isabelle_thm" "Bad mapping"))
  1291 		       | NONE => (message "NO2";error "get_isabelle_thm" "Bad mapping"))
  1290 		  | NONE => (message "NO1";error "get_isabelle_thm" "Bad mapping")
  1292 		  | NONE => (message "NO1";error "get_isabelle_thm" "Bad mapping")
  1291 	    end
  1293 	    end
  1292 	  | SOME NONE => error ("Trying to access ignored theorem " ^ thmname)
  1294 	  | SOME NONE => error ("Trying to access ignored theorem " ^ thmname)
  1293 	  | NONE =>
  1295 	  | NONE =>
  1294 	    let		
  1296 	    let
  1295 		val _ = (message "Looking for conclusion:";
  1297 		val _ = (message "Looking for conclusion:";
  1296 			 if_debug prin isaconc)
  1298 			 if_debug prin isaconc)
  1297 		val cs = non_trivial_term_consts isaconc
  1299 		val cs = non_trivial_term_consts isaconc
  1298 		val _ = (message "Looking for consts:";
  1300 		val _ = (message "Looking for consts:";
  1299 			 message (commas cs))
  1301 			 message (commas cs))
  1323         let
  1325         let
  1324 	    val (info,hol4conc') = disamb_term hol4conc
  1326 	    val (info,hol4conc') = disamb_term hol4conc
  1325 	    val i2h_conc = symmetric (rewrite_hol4_term (HOLogic.mk_Trueprop hol4conc') thy)
  1327 	    val i2h_conc = symmetric (rewrite_hol4_term (HOLogic.mk_Trueprop hol4conc') thy)
  1326 	in
  1328 	in
  1327 	    case concl_of i2h_conc of
  1329 	    case concl_of i2h_conc of
  1328 		Const("==",_) $ lhs $ _ => 
  1330 		Const("==",_) $ lhs $ _ =>
  1329 		(warning ("Failed lookup of theorem '"^thmname^"':");
  1331 		(warning ("Failed lookup of theorem '"^thmname^"':");
  1330 	         writeln "Original conclusion:";
  1332 	         writeln "Original conclusion:";
  1331 		 prin hol4conc';
  1333 		 prin hol4conc';
  1332 		 writeln "Modified conclusion:";
  1334 		 writeln "Modified conclusion:";
  1333 		 prin lhs)
  1335 		 prin lhs)
  1334 	      | _ => ()
  1336 	      | _ => ()
  1335 	end
  1337 	end
  1336   in
  1338   in
  1337       case b of 
  1339       case b of
  1338 	  NONE => (warn () handle _ => (); (a,b))
  1340 	  NONE => (warn () handle _ => (); (a,b))
  1339 	| _ => (a, b)
  1341 	| _ => (a, b)
  1340   end 
  1342   end
  1341 
  1343 
  1342 fun get_thm thyname thmname thy =
  1344 fun get_thm thyname thmname thy =
  1343     case get_hol4_thm thyname thmname thy of
  1345     case get_hol4_thm thyname thmname thy of
  1344 	SOME hth => (thy,SOME hth)
  1346 	SOME hth => (thy,SOME hth)
  1345       | NONE => ((case import_proof_concl thyname thmname thy of
  1347       | NONE => ((case import_proof_concl thyname thmname thy of
  1371     let
  1373     let
  1372 	val (hth' as HOLThm (args as (_,th))) = norm_hthm thy hth
  1374 	val (hth' as HOLThm (args as (_,th))) = norm_hthm thy hth
  1373 	val rew = rewrite_hol4_term (concl_of th) thy
  1375 	val rew = rewrite_hol4_term (concl_of th) thy
  1374 	val th  = equal_elim rew th
  1376 	val th  = equal_elim rew th
  1375 	val thy' = add_hol4_pending thyname thmname args thy
  1377 	val thy' = add_hol4_pending thyname thmname args thy
  1376 	val _ = ImportRecorder.add_hol_pending thyname thmname (hthm2thm hth') 
  1378 	val _ = ImportRecorder.add_hol_pending thyname thmname (hthm2thm hth')
  1377         val th = disambiguate_frees th
  1379         val th = disambiguate_frees th
  1378 	val thy2 = if gen_output
  1380 	val thy2 = if gen_output
  1379 		   then add_dump ("lemma " ^ (quotename thmname) ^ ": " ^ 
  1381 		   then add_dump ("lemma " ^ (quotename thmname) ^ ": " ^
  1380                                   (smart_string_of_thm th) ^ "\n  by (import " ^ 
  1382                                   (smart_string_of_thm th) ^ "\n  by (import " ^
  1381                                   thyname ^ " " ^ (quotename thmname) ^ ")") thy'
  1383                                   thyname ^ " " ^ (quotename thmname) ^ ")") thy'
  1382 		   else thy'
  1384 		   else thy'
  1383     in
  1385     in
  1384 	(thy2,hth')
  1386 	(thy2,hth')
  1385     end
  1387     end
  1766 	val _ = message "RESULT:"
  1768 	val _ = message "RESULT:"
  1767 	val _ = if_debug pth res
  1769 	val _ = if_debug pth res
  1768     in
  1770     in
  1769 	(thy,res)
  1771 	(thy,res)
  1770     end
  1772     end
  1771 	
  1773 
  1772 
  1774 
  1773 fun CCONTR tm hth thy =
  1775 fun CCONTR tm hth thy =
  1774     let
  1776     let
  1775 	val _ = message "SPEC:"
  1777 	val _ = message "SPEC:"
  1776 	val _ = if_debug prin tm
  1778 	val _ = if_debug prin tm
  1849 			      in
  1851 			      in
  1850 				  mk_COMB (mk_REFL cc) (mk_ABS v th thy) thy
  1852 				  mk_COMB (mk_REFL cc) (mk_ABS v th thy) thy
  1851 			      end) th vlist'
  1853 			      end) th vlist'
  1852 		end
  1854 		end
  1853 	      | SOME _ => raise ERR "GEN_ABS" "Bad constant"
  1855 	      | SOME _ => raise ERR "GEN_ABS" "Bad constant"
  1854 	      | NONE => 
  1856 	      | NONE =>
  1855 		foldr (fn (v,th) => mk_ABS v th thy) th vlist'
  1857 		foldr (fn (v,th) => mk_ABS v th thy) th vlist'
  1856 	val res = HOLThm(rens_of info',th1)
  1858 	val res = HOLThm(rens_of info',th1)
  1857 	val _ = message "RESULT:"
  1859 	val _ = message "RESULT:"
  1858 	val _ = if_debug pth res
  1860 	val _ = if_debug pth res
  1859     in
  1861     in
  1945 			    val p1 = quotename constname
  1947 			    val p1 = quotename constname
  1946 			    val p2 = string_of_ctyp (ctyp_of thy'' ctype)
  1948 			    val p2 = string_of_ctyp (ctyp_of thy'' ctype)
  1947 			    val p3 = string_of_mixfix csyn
  1949 			    val p3 = string_of_mixfix csyn
  1948 			    val p4 = smart_string_of_cterm crhs
  1950 			    val p4 = smart_string_of_cterm crhs
  1949 			in
  1951 			in
  1950 			    add_dump ("constdefs\n  " ^p1^ " :: \"" ^p2^ "\" "^p3^ "\n  " ^p4) thy''  
  1952 			    add_dump ("constdefs\n  " ^p1^ " :: \"" ^p2^ "\" "^p3^ "\n  " ^p4) thy''
  1951 			end
  1953 			end
  1952 		    else
  1954 		    else
  1953 			(add_dump ("consts\n  " ^ (quotename constname) ^ " :: \"" ^ string_of_ctyp (ctyp_of thy'' ctype) ^
  1955 			(add_dump ("consts\n  " ^ (quotename constname) ^ " :: \"" ^ string_of_ctyp (ctyp_of thy'' ctype) ^
  1954 				   "\" " ^ (string_of_mixfix csyn) ^ "\n\ndefs\n  " ^ (quotename thmname) ^ ": " ^ (smart_string_of_cterm crhs))
  1956 				   "\" " ^ (string_of_mixfix csyn) ^ "\n\ndefs\n  " ^ (quotename thmname) ^ ": " ^ (smart_string_of_cterm crhs))
  1955 				  thy'')
  1957 				  thy'')
  1956 	val hth = case Shuffler.set_prop thy22 (HOLogic.mk_Trueprop tm24) [("",th)] of
  1958 	val hth = case Shuffler.set_prop thy22 (HOLogic.mk_Trueprop tm24) [("",th)] of
  1957 		      SOME (_,res) => HOLThm(rens_of linfo,res)
  1959 		      SOME (_,res) => HOLThm(rens_of linfo,res)
  1958 		    | NONE => raise ERR "new_definition" "Bad conclusion"
  1960 		    | NONE => raise ERR "new_definition" "Bad conclusion"
  1959 	val fullname = Sign.full_name thy22 thmname
  1961 	val fullname = Sign.full_name thy22 thmname
  1960 	val thy22' = case opt_get_output_thy thy22 of
  1962 	val thy22' = case opt_get_output_thy thy22 of
  1961 			 "" => (ImportRecorder.add_hol_mapping thyname thmname fullname; 
  1963 			 "" => (ImportRecorder.add_hol_mapping thyname thmname fullname;
  1962 				add_hol4_mapping thyname thmname fullname thy22)
  1964 				add_hol4_mapping thyname thmname fullname thy22)
  1963 		       | output_thy =>
  1965 		       | output_thy =>
  1964 			 let
  1966 			 let
  1965 			     val moved_thmname = output_thy ^ "." ^ thyname ^ "." ^ thmname
  1967 			     val moved_thmname = output_thy ^ "." ^ thyname ^ "." ^ thmname
  1966 			     val _ = ImportRecorder.add_hol_move fullname moved_thmname
  1968 			     val _ = ImportRecorder.add_hol_move fullname moved_thmname
  1980     val helper = thm "termspec_help"
  1982     val helper = thm "termspec_help"
  1981 in
  1983 in
  1982 fun new_specification thyname thmname names hth thy =
  1984 fun new_specification thyname thmname names hth thy =
  1983     case HOL4DefThy.get thy of
  1985     case HOL4DefThy.get thy of
  1984 	Replaying _ => (thy,hth)
  1986 	Replaying _ => (thy,hth)
  1985       | _ => 
  1987       | _ =>
  1986 	let
  1988 	let
  1987 	    val _ = message "NEW_SPEC:"
  1989 	    val _ = message "NEW_SPEC:"
  1988 	    val _ = if_debug pth hth
  1990 	    val _ = if_debug pth hth
  1989 	    val names = map (rename_const thyname thy) names
  1991 	    val names = map (rename_const thyname thy) names
  1990 	    val _ = warning ("Introducing constants " ^ commas names)
  1992 	    val _ = warning ("Introducing constants " ^ commas names)
  2003 				   handle TYPE _ => raise ERR "new_specification" "not an abstraction type"
  2005 				   handle TYPE _ => raise ERR "new_specification" "not an abstraction type"
  2004 			       fun dest_exists (Const("Ex",_) $ abody) =
  2006 			       fun dest_exists (Const("Ex",_) $ abody) =
  2005 				   dest_eta_abs abody
  2007 				   dest_eta_abs abody
  2006 				 | dest_exists tm =
  2008 				 | dest_exists tm =
  2007 				   raise ERR "new_specification" "Bad existential formula"
  2009 				   raise ERR "new_specification" "Bad existential formula"
  2008 					 
  2010 
  2009 			       val (consts,_) = Library.foldl (fn ((cs,ex),cname) =>
  2011 			       val (consts,_) = Library.foldl (fn ((cs,ex),cname) =>
  2010 							  let
  2012 							  let
  2011 							      val (_,cT,p) = dest_exists ex
  2013 							      val (_,cT,p) = dest_exists ex
  2012 							  in
  2014 							  in
  2013 							      ((cname,cT,mk_syn thy cname)::cs,p)
  2015 							      ((cname,cT,mk_syn thy cname)::cs,p)
  2054 	    val _ = if_debug pth hth
  2056 	    val _ = if_debug pth hth
  2055 	in
  2057 	in
  2056 	    intern_store_thm false thyname thmname hth thy''
  2058 	    intern_store_thm false thyname thmname hth thy''
  2057 	end
  2059 	end
  2058 	handle e => (message "exception in new_specification"; print_exn e)
  2060 	handle e => (message "exception in new_specification"; print_exn e)
  2059 		    
  2061 
  2060 end
  2062 end
  2061 			   
  2063 
  2062 fun new_axiom name tm thy = raise ERR "new_axiom" ("Oh, no you don't! (" ^ name ^ ")")
  2064 fun new_axiom name tm thy = raise ERR "new_axiom" ("Oh, no you don't! (" ^ name ^ ")")
  2063 				      
  2065 
  2064 fun to_isa_thm (hth as HOLThm(_,th)) =
  2066 fun to_isa_thm (hth as HOLThm(_,th)) =
  2065     let
  2067     let
  2066 	val (HOLThm args) = norm_hthm (theory_of_thm th) hth
  2068 	val (HOLThm args) = norm_hthm (theory_of_thm th) hth
  2067     in
  2069     in
  2068 	apsnd strip_shyps args
  2070 	apsnd strip_shyps args
  2077     val typedef_hol2hollight = thm "typedef_hol2hollight"
  2079     val typedef_hol2hollight = thm "typedef_hol2hollight"
  2078 in
  2080 in
  2079 fun new_type_definition thyname thmname tycname hth thy =
  2081 fun new_type_definition thyname thmname tycname hth thy =
  2080     case HOL4DefThy.get thy of
  2082     case HOL4DefThy.get thy of
  2081 	Replaying _ => (thy,hth)
  2083 	Replaying _ => (thy,hth)
  2082       | _ => 
  2084       | _ =>
  2083 	let
  2085 	let
  2084 	    val _ = message "TYPE_DEF:"
  2086 	    val _ = message "TYPE_DEF:"
  2085 	    val _ = if_debug pth hth
  2087 	    val _ = if_debug pth hth
  2086 	    val _ = warning ("Introducing type " ^ tycname)
  2088 	    val _ = warning ("Introducing type " ^ tycname)
  2087 	    val (HOLThm(rens,td_th)) = norm_hthm thy hth
  2089 	    val (HOLThm(rens,td_th)) = norm_hthm thy hth
  2091 		      | _ => raise ERR "new_type_definition" "Bad type definition theorem"
  2093 		      | _ => raise ERR "new_type_definition" "Bad type definition theorem"
  2092 	    val tfrees = term_tfrees c
  2094 	    val tfrees = term_tfrees c
  2093 	    val tnames = map fst tfrees
  2095 	    val tnames = map fst tfrees
  2094 	    val tsyn = mk_syn thy tycname
  2096 	    val tsyn = mk_syn thy tycname
  2095 	    val typ = (tycname,tnames,tsyn)
  2097 	    val typ = (tycname,tnames,tsyn)
  2096 	    val ((_, typedef_info), thy') = TypedefPackage.add_typedef_i false (SOME thmname) typ c NONE (rtac th2 1) thy	    
  2098 	    val ((_, typedef_info), thy') = TypedefPackage.add_typedef_i false (SOME thmname) typ c NONE (rtac th2 1) thy
  2097             val _ = ImportRecorder.add_typedef (SOME thmname) typ c NONE th2
  2099             val _ = ImportRecorder.add_typedef (SOME thmname) typ c NONE th2
  2098 				      
  2100 
  2099 	    val th3 = (#type_definition typedef_info) RS typedef_hol2hol4
  2101 	    val th3 = (#type_definition typedef_info) RS typedef_hol2hol4
  2100 
  2102 
  2101 	    val fulltyname = Sign.intern_type thy' tycname
  2103 	    val fulltyname = Sign.intern_type thy' tycname
  2102 	    val thy'' = add_hol4_type_mapping thyname tycname true fulltyname thy'
  2104 	    val thy'' = add_hol4_type_mapping thyname tycname true fulltyname thy'
  2103 	    val _ = ImportRecorder.add_hol_type_mapping thyname tycname fulltyname
  2105 	    val _ = ImportRecorder.add_hol_type_mapping thyname tycname fulltyname
  2122 				then ""
  2124 				then ""
  2123 				else "(" ^ commas tnames ^ ") "
  2125 				else "(" ^ commas tnames ^ ") "
  2124 	    val proc_prop = if null tnames
  2126 	    val proc_prop = if null tnames
  2125 			    then smart_string_of_cterm
  2127 			    then smart_string_of_cterm
  2126 			    else Library.setmp show_all_types true smart_string_of_cterm
  2128 			    else Library.setmp show_all_types true smart_string_of_cterm
  2127 	    val thy5 = add_dump ("typedef (open) " ^ tnames_string ^ (quotename tycname) ^ " = " ^ (proc_prop (cterm_of thy4 c)) ^ " " 
  2129 	    val thy5 = add_dump ("typedef (open) " ^ tnames_string ^ (quotename tycname) ^ " = " ^ (proc_prop (cterm_of thy4 c)) ^ " "
  2128 				 ^ (string_of_mixfix tsyn) ^ "\n  by (rule typedef_helper,import " ^ thyname ^ " " ^ thmname ^ ")") thy4
  2130 				 ^ (string_of_mixfix tsyn) ^ "\n  by (rule typedef_helper,import " ^ thyname ^ " " ^ thmname ^ ")") thy4
  2129 	    
  2131 
  2130 	    val thy6 = add_dump ("lemmas " ^ thmname ^ " = typedef_hol2hol4 [OF type_definition_" ^ tycname ^ "]") thy5
  2132 	    val thy6 = add_dump ("lemmas " ^ thmname ^ " = typedef_hol2hol4 [OF type_definition_" ^ tycname ^ "]") thy5
  2131               
  2133 
  2132 	    val _ = message "RESULT:"
  2134 	    val _ = message "RESULT:"
  2133 	    val _ = if_debug pth hth'
  2135 	    val _ = if_debug pth hth'
  2134 	in
  2136 	in
  2135 	    (thy6,hth')
  2137 	    (thy6,hth')
  2136 	end
  2138 	end
  2143 	val syn = string_of_mixfix (mk_syn thy constname)
  2145 	val syn = string_of_mixfix (mk_syn thy constname)
  2144 	(*val eq = smart_string_of_cterm (cterm_of thy (Const(rhs, ty)))*)
  2146 	(*val eq = smart_string_of_cterm (cterm_of thy (Const(rhs, ty)))*)
  2145         val eq = quote (constname ^ " == "^rhs)
  2147         val eq = quote (constname ^ " == "^rhs)
  2146 	val d = case defname of NONE => "" | SOME defname => (quotename defname)^" : "
  2148 	val d = case defname of NONE => "" | SOME defname => (quotename defname)^" : "
  2147     in
  2149     in
  2148 	add_dump ("constdefs\n  " ^ n ^ " :: \"" ^ t ^ "\" " ^ syn ^ "\n  " ^ d ^ eq) thy    
  2150 	add_dump ("constdefs\n  " ^ n ^ " :: \"" ^ t ^ "\" " ^ syn ^ "\n  " ^ d ^ eq) thy
  2149     end
  2151     end
  2150 
  2152 
  2151 fun add_dump_syntax thy name = 
  2153 fun add_dump_syntax thy name =
  2152     let
  2154     let
  2153       val n = quotename name
  2155       val n = quotename name
  2154       val syn = string_of_mixfix (mk_syn thy name)
  2156       val syn = string_of_mixfix (mk_syn thy name)
  2155     in
  2157     in
  2156       add_dump ("syntax\n  "^n^" :: _ "^syn) thy
  2158       add_dump ("syntax\n  "^n^" :: _ "^syn) thy
  2157     end
  2159     end
  2158       
  2160 
  2159 (*val type_intro_replay_history = ref (Symtab.empty:unit Symtab.table)
  2161 (*val type_intro_replay_history = ref (Symtab.empty:unit Symtab.table)
  2160 fun choose_upon_replay_history thy s dth = 
  2162 fun choose_upon_replay_history thy s dth =
  2161     case Symtab.lookup (!type_intro_replay_history) s of
  2163     case Symtab.lookup (!type_intro_replay_history) s of
  2162 	NONE => (type_intro_replay_history := Symtab.update (s, ()) (!type_intro_replay_history); dth)
  2164 	NONE => (type_intro_replay_history := Symtab.update (s, ()) (!type_intro_replay_history); dth)
  2163       | SOME _ => HOLThm([], PureThy.get_thm thy (PureThy.Name s))
  2165       | SOME _ => HOLThm([], PureThy.get_thm thy (PureThy.Name s))
  2164 *)
  2166 *)
  2165 
  2167 
  2166 fun type_introduction thyname thmname tycname abs_name rep_name (P,t) hth thy =
  2168 fun type_introduction thyname thmname tycname abs_name rep_name (P,t) hth thy =
  2167     case HOL4DefThy.get thy of
  2169     case HOL4DefThy.get thy of
  2168 	Replaying _ => (thy,
  2170 	Replaying _ => (thy,
  2169           HOLThm([], PureThy.get_thm thy (PureThy.Name (thmname^"_@intern"))) handle ERROR _ => hth)
  2171           HOLThm([], PureThy.get_thm thy (PureThy.Name (thmname^"_@intern"))) handle ERROR _ => hth)
  2170       | _ => 
  2172       | _ =>
  2171 	let
  2173 	let
  2172             val _ = message "TYPE_INTRO:"
  2174             val _ = message "TYPE_INTRO:"
  2173 	    val _ = if_debug pth hth
  2175 	    val _ = if_debug pth hth
  2174 	    val _ = warning ("Introducing type " ^ tycname ^ " (with morphisms " ^ abs_name ^ " and " ^ rep_name ^ ")")
  2176 	    val _ = warning ("Introducing type " ^ tycname ^ " (with morphisms " ^ abs_name ^ " and " ^ rep_name ^ ")")
  2175 	    val (HOLThm(rens,td_th)) = norm_hthm thy hth
  2177 	    val (HOLThm(rens,td_th)) = norm_hthm thy hth
  2190 	    val _ = ImportRecorder.add_typedef NONE typ c (SOME(rep_name,abs_name)) th2
  2192 	    val _ = ImportRecorder.add_typedef NONE typ c (SOME(rep_name,abs_name)) th2
  2191 	    val fulltyname = Sign.intern_type thy' tycname
  2193 	    val fulltyname = Sign.intern_type thy' tycname
  2192 	    val aty = Type (fulltyname, map mk_vartype tnames)
  2194 	    val aty = Type (fulltyname, map mk_vartype tnames)
  2193 	    val abs_ty = tT --> aty
  2195 	    val abs_ty = tT --> aty
  2194 	    val rep_ty = aty --> tT
  2196 	    val rep_ty = aty --> tT
  2195             val typedef_hol2hollight' = 
  2197             val typedef_hol2hollight' =
  2196 		Drule.instantiate' 
  2198 		Drule.instantiate'
  2197 		    [SOME (ctyp_of thy' aty), SOME (ctyp_of thy' tT)] 
  2199 		    [SOME (ctyp_of thy' aty), SOME (ctyp_of thy' tT)]
  2198 		    [NONE, NONE, NONE, SOME (cterm_of thy' (Free ("a", aty))), SOME (cterm_of thy' (Free ("r", tT)))]
  2200 		    [NONE, NONE, NONE, SOME (cterm_of thy' (Free ("a", aty))), SOME (cterm_of thy' (Free ("r", tT)))]
  2199                     typedef_hol2hollight
  2201                     typedef_hol2hollight
  2200 	    val th4 = (#type_definition typedef_info) RS typedef_hol2hollight'
  2202 	    val th4 = (#type_definition typedef_info) RS typedef_hol2hollight'
  2201             val _ = null (Thm.fold_terms Term.add_tvars th4 []) orelse
  2203             val _ = null (Thm.fold_terms Term.add_tvars th4 []) orelse
  2202               raise ERR "type_introduction" "no type variables expected any more"
  2204               raise ERR "type_introduction" "no type variables expected any more"
  2207 	    val _ = ImportRecorder.add_hol_type_mapping thyname tycname fulltyname
  2209 	    val _ = ImportRecorder.add_hol_type_mapping thyname tycname fulltyname
  2208             val _ = message "step 4"
  2210             val _ = message "step 4"
  2209 	    val (hth' as HOLThm args) = norm_hthm thy'' (HOLThm(rens,th4))
  2211 	    val (hth' as HOLThm args) = norm_hthm thy'' (HOLThm(rens,th4))
  2210 	    val thy4 = add_hol4_pending thyname thmname args thy''
  2212 	    val thy4 = add_hol4_pending thyname thmname args thy''
  2211 	    val _ = ImportRecorder.add_hol_pending thyname thmname (hthm2thm hth')
  2213 	    val _ = ImportRecorder.add_hol_pending thyname thmname (hthm2thm hth')
  2212 	   
  2214 
  2213 	    val P' = P (* why !? #2 (Logic.dest_equals (concl_of (rewrite_hol4_term P thy4))) *)
  2215 	    val P' = P (* why !? #2 (Logic.dest_equals (concl_of (rewrite_hol4_term P thy4))) *)
  2214 	    val c   =
  2216 	    val c   =
  2215 		let
  2217 		let
  2216 		    val PT = type_of P'
  2218 		    val PT = type_of P'
  2217 		in
  2219 		in
  2218 		    Const("Collect",PT-->HOLogic.mk_setT (domain_type PT)) $ P'
  2220 		    Const("Collect",PT-->HOLogic.mk_setT (domain_type PT)) $ P'
  2219 		end
  2221 		end
  2220 	    
  2222 
  2221 	    val tnames_string = if null tnames
  2223 	    val tnames_string = if null tnames
  2222 				then ""
  2224 				then ""
  2223 				else "(" ^ commas tnames ^ ") "
  2225 				else "(" ^ commas tnames ^ ") "
  2224 	    val proc_prop = if null tnames
  2226 	    val proc_prop = if null tnames
  2225 			    then smart_string_of_cterm
  2227 			    then smart_string_of_cterm
  2226 			    else Library.setmp show_all_types true smart_string_of_cterm
  2228 			    else Library.setmp show_all_types true smart_string_of_cterm
  2227 	    val thy = add_dump ("typedef (open) " ^ tnames_string ^ (quotename tycname) ^ 
  2229 	    val thy = add_dump ("typedef (open) " ^ tnames_string ^ (quotename tycname) ^
  2228               " = " ^ (proc_prop (cterm_of thy4 c)) ^ " " ^ 
  2230               " = " ^ (proc_prop (cterm_of thy4 c)) ^ " " ^
  2229 	      (string_of_mixfix tsyn) ^ " morphisms "^
  2231 	      (string_of_mixfix tsyn) ^ " morphisms "^
  2230               (quote rep_name)^" "^(quote abs_name)^"\n"^ 
  2232               (quote rep_name)^" "^(quote abs_name)^"\n"^
  2231 	      ("  apply (rule light_ex_imp_nonempty[where t="^
  2233 	      ("  apply (rule light_ex_imp_nonempty[where t="^
  2232               (proc_prop (cterm_of thy4 t))^"])\n"^              
  2234               (proc_prop (cterm_of thy4 t))^"])\n"^
  2233 	      ("  by (import " ^ thyname ^ " " ^ (quotename thmname) ^ ")"))) thy4
  2235 	      ("  by (import " ^ thyname ^ " " ^ (quotename thmname) ^ ")"))) thy4
  2234 	    val str_aty = string_of_ctyp (ctyp_of thy aty)
  2236 	    val str_aty = string_of_ctyp (ctyp_of thy aty)
  2235             val thy = add_dump_syntax thy rep_name 
  2237             val thy = add_dump_syntax thy rep_name
  2236             val thy = add_dump_syntax thy abs_name
  2238             val thy = add_dump_syntax thy abs_name
  2237 	    val thy = add_dump ("lemmas " ^ (quote (thmname^"_@intern")) ^ 
  2239 	    val thy = add_dump ("lemmas " ^ (quote (thmname^"_@intern")) ^
  2238               " = typedef_hol2hollight \n"^
  2240               " = typedef_hol2hollight \n"^
  2239               "  [where a=\"a :: "^str_aty^"\" and r=r" ^
  2241               "  [where a=\"a :: "^str_aty^"\" and r=r" ^
  2240 	      " ,\n   OF "^(quotename ("type_definition_" ^ tycname)) ^ "]") thy 
  2242 	      " ,\n   OF "^(quotename ("type_definition_" ^ tycname)) ^ "]") thy
  2241 	    val _ = message "RESULT:"
  2243 	    val _ = message "RESULT:"
  2242 	    val _ = if_debug pth hth'
  2244 	    val _ = if_debug pth hth'
  2243 	in
  2245 	in
  2244 	    (thy,hth')
  2246 	    (thy,hth')
  2245 	end
  2247 	end