src/HOL/Nominal/nominal_atoms.ML
changeset 20097 be2d96bbf39c
parent 20046 9c8909fc5865
child 20179 a2f3f523c84b
equal deleted inserted replaced
20096:7058714024b3 20097:be2d96bbf39c
    33 
    33 
    34 structure NominalData = TheoryDataFun(NominalArgs);
    34 structure NominalData = TheoryDataFun(NominalArgs);
    35 
    35 
    36 fun atoms_of thy = map fst (Symtab.dest (NominalData.get thy));
    36 fun atoms_of thy = map fst (Symtab.dest (NominalData.get thy));
    37 
    37 
    38 (* FIXME: add to hologic.ML ? *)
    38 fun mk_permT T = HOLogic.listT (HOLogic.mk_prodT (T, T));
    39 fun mk_listT T = Type ("List.list", [T]);
       
    40 fun mk_permT T = mk_listT (HOLogic.mk_prodT (T, T));
       
    41 
    39 
    42 fun mk_Cons x xs =
    40 fun mk_Cons x xs =
    43   let val T = fastype_of x
    41   let val T = fastype_of x
    44   in Const ("List.list.Cons", T --> mk_listT T --> mk_listT T) $ x $ xs end;
    42   in Const ("List.list.Cons", T --> HOLogic.listT T --> HOLogic.listT T) $ x $ xs end;
    45 
    43 
    46 
    44 
    47 (* this function sets up all matters related to atom-  *)
    45 (* this function sets up all matters related to atom-  *)
    48 (* kinds; the user specifies a list of atom-kind names *)
    46 (* kinds; the user specifies a list of atom-kind names *)
    49 (* atom_decl <ak1> ... <akn>                           *)
    47 (* atom_decl <ak1> ... <akn>                           *)
   367 	       end
   365 	       end
   368            else 
   366            else 
   369             ([],thy')))  (* do nothing branch, if ak_name = ak_name' *) 
   367             ([],thy')))  (* do nothing branch, if ak_name = ak_name' *) 
   370 	    ak_names_types thy) ak_names_types thy12c;
   368 	    ak_names_types thy) ak_names_types thy12c;
   371 
   369 
   372      (*<<<<<<<  pt_<ak> class instances  >>>>>>>*)
   370      (********  pt_<ak> class instances  ********)
   373      (*=========================================*)
   371      (*=========================================*)
   374      (* some abbreviations for theorems *)
   372      (* some abbreviations for theorems *)
   375       val pt1           = thm "pt1";
   373       val pt1           = thm "pt1";
   376       val pt2           = thm "pt2";
   374       val pt2           = thm "pt2";
   377       val pt3           = thm "pt3";
   375       val pt3           = thm "pt3";
   423      val thy18 = fold (fn ak_name => fn thy =>
   421      val thy18 = fold (fn ak_name => fn thy =>
   424        let
   422        let
   425           val cls_name = Sign.full_name (sign_of thy) ("pt_"^ak_name);
   423           val cls_name = Sign.full_name (sign_of thy) ("pt_"^ak_name);
   426           val at_thm   = PureThy.get_thm thy (Name ("at_"^ak_name^"_inst"));
   424           val at_thm   = PureThy.get_thm thy (Name ("at_"^ak_name^"_inst"));
   427           val pt_inst  = PureThy.get_thm thy (Name ("pt_"^ak_name^"_inst"));
   425           val pt_inst  = PureThy.get_thm thy (Name ("pt_"^ak_name^"_inst"));
   428           
   426 
   429           fun pt_proof thm = 
   427           fun pt_proof thm = 
   430 	      EVERY [ClassPackage.intro_classes_tac [],
   428               EVERY [ClassPackage.intro_classes_tac [],
   431                      rtac (thm RS pt1) 1, rtac (thm RS pt2) 1, rtac (thm RS pt3) 1, atac 1];
   429                      rtac (thm RS pt1) 1, rtac (thm RS pt2) 1, rtac (thm RS pt3) 1, atac 1];
   432 
   430 
   433           val pt_thm_fun   = at_thm RS (pt_inst RS (pt_inst RS pt_fun_inst));
   431           val pt_thm_fun   = at_thm RS (pt_inst RS (pt_inst RS pt_fun_inst));
   434           val pt_thm_noptn = pt_inst RS pt_noptn_inst; 
   432           val pt_thm_noptn = pt_inst RS pt_noptn_inst; 
   435           val pt_thm_optn  = pt_inst RS pt_optn_inst; 
   433           val pt_thm_optn  = pt_inst RS pt_optn_inst; 
   436           val pt_thm_list  = pt_inst RS pt_list_inst;
   434           val pt_thm_list  = pt_inst RS pt_list_inst;
   437           val pt_thm_prod  = pt_inst RS (pt_inst RS pt_prod_inst);
   435           val pt_thm_prod  = pt_inst RS (pt_inst RS pt_prod_inst);
   438           val pt_thm_nprod = pt_inst RS (pt_inst RS pt_nprod_inst);
   436           val pt_thm_nprod = pt_inst RS (pt_inst RS pt_nprod_inst);
   439           val pt_thm_unit  = pt_unit_inst;
   437           val pt_thm_unit  = pt_unit_inst;
   440           val pt_thm_set   = pt_inst RS pt_set_inst
   438           val pt_thm_set   = pt_inst RS pt_set_inst
   441        in 
   439        in
   442 	thy
   440         thy
   443 	|> AxClass.prove_arity ("fun",[[cls_name],[cls_name]],[cls_name]) (pt_proof pt_thm_fun)
   441         |> AxClass.prove_arity ("fun",[[cls_name],[cls_name]],[cls_name]) (pt_proof pt_thm_fun)
   444         |> AxClass.prove_arity ("Nominal.noption",[[cls_name]],[cls_name]) (pt_proof pt_thm_noptn) 
   442         |> AxClass.prove_arity ("Nominal.noption",[[cls_name]],[cls_name]) (pt_proof pt_thm_noptn) 
   445         |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (pt_proof pt_thm_optn)
   443         |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (pt_proof pt_thm_optn)
   446         |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (pt_proof pt_thm_list)
   444         |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (pt_proof pt_thm_list)
   447         |> AxClass.prove_arity ("*",[[cls_name],[cls_name]],[cls_name]) (pt_proof pt_thm_prod)
   445         |> AxClass.prove_arity ("*",[[cls_name],[cls_name]],[cls_name]) (pt_proof pt_thm_prod)
   448         |> AxClass.prove_arity ("Nominal.nprod",[[cls_name],[cls_name]],[cls_name]) 
   446         |> AxClass.prove_arity ("Nominal.nprod",[[cls_name],[cls_name]],[cls_name]) 
   449                                     (pt_proof pt_thm_nprod)
   447                                     (pt_proof pt_thm_nprod)
   450         |> AxClass.prove_arity ("Product_Type.unit",[],[cls_name]) (pt_proof pt_thm_unit)
   448         |> AxClass.prove_arity ("Product_Type.unit",[],[cls_name]) (pt_proof pt_thm_unit)
   451         |> AxClass.prove_arity ("set",[[cls_name]],[cls_name]) (pt_proof pt_thm_set)
   449         |> AxClass.prove_arity ("set",[[cls_name]],[cls_name]) (pt_proof pt_thm_set)
   452      end) ak_names thy13; 
   450      end) ak_names thy13; 
   453 
   451 
   454        (*<<<<<<<  fs_<ak> class instances  >>>>>>>*)
   452        (********  fs_<ak> class instances  ********)
   455        (*=========================================*)
   453        (*=========================================*)
   456        (* abbreviations for some lemmas *)
   454        (* abbreviations for some lemmas *)
   457        val fs1            = thm "fs1";
   455        val fs1            = thm "fs1";
   458        val fs_at_inst     = thm "fs_at_inst";
   456        val fs_at_inst     = thm "fs_at_inst";
   459        val fs_unit_inst   = thm "fs_unit_inst";
   457        val fs_unit_inst   = thm "fs_unit_inst";
   464        val dj_supp        = thm "dj_supp"
   462        val dj_supp        = thm "dj_supp"
   465 
   463 
   466        (* shows that <ak> is an instance of fs_<ak>     *)
   464        (* shows that <ak> is an instance of fs_<ak>     *)
   467        (* uses the theorem at_<ak>_inst                 *)
   465        (* uses the theorem at_<ak>_inst                 *)
   468        val thy20 = fold (fn ak_name => fn thy =>
   466        val thy20 = fold (fn ak_name => fn thy =>
   469 	fold (fn ak_name' => fn thy' => 
   467         fold (fn ak_name' => fn thy' =>
   470         let
   468         let
   471            val qu_name =  Sign.full_name (sign_of thy') ak_name';
   469            val qu_name =  Sign.full_name (sign_of thy') ak_name';
   472            val qu_class = Sign.full_name (sign_of thy') ("fs_"^ak_name);
   470            val qu_class = Sign.full_name (sign_of thy') ("fs_"^ak_name);
   473            val proof = 
   471            val proof =
   474 	       (if ak_name = ak_name'
   472                (if ak_name = ak_name'
   475 	        then
   473                 then
   476 	          let val at_thm = PureThy.get_thm thy' (Name ("at_"^ak_name^"_inst"));
   474                   let val at_thm = PureThy.get_thm thy' (Name ("at_"^ak_name^"_inst"));
   477                   in  EVERY [ClassPackage.intro_classes_tac [],
   475                   in  EVERY [ClassPackage.intro_classes_tac [],
   478                              rtac ((at_thm RS fs_at_inst) RS fs1) 1] end
   476                              rtac ((at_thm RS fs_at_inst) RS fs1) 1] end
   479                 else
   477                 else
   480 		  let val dj_inst = PureThy.get_thm thy' (Name ("dj_"^ak_name'^"_"^ak_name));
   478                   let val dj_inst = PureThy.get_thm thy' (Name ("dj_"^ak_name'^"_"^ak_name));
   481                       val simp_s = HOL_basic_ss addsimps [dj_inst RS dj_supp, Finites.emptyI]; 
   479                       val simp_s = HOL_basic_ss addsimps [dj_inst RS dj_supp, Finites.emptyI];
   482                   in EVERY [ClassPackage.intro_classes_tac [], asm_simp_tac simp_s 1] end)      
   480                   in EVERY [ClassPackage.intro_classes_tac [], asm_simp_tac simp_s 1] end)
   483         in 
   481         in
   484 	 AxClass.prove_arity (qu_name,[],[qu_class]) proof thy' 
   482          AxClass.prove_arity (qu_name,[],[qu_class]) proof thy'
   485         end) ak_names thy) ak_names thy18;
   483         end) ak_names thy) ak_names thy18;
   486 
   484 
   487        (* shows that                  *)
   485        (* shows that                  *)
   488        (*    unit                     *)
   486        (*    unit                     *)
   489        (*    *(fs_<ak>,fs_<ak>)       *)
   487        (*    *(fs_<ak>,fs_<ak>)       *)
   494 
   492 
   495        val thy24 = fold (fn ak_name => fn thy => 
   493        val thy24 = fold (fn ak_name => fn thy => 
   496         let
   494         let
   497           val cls_name = Sign.full_name (sign_of thy) ("fs_"^ak_name);
   495           val cls_name = Sign.full_name (sign_of thy) ("fs_"^ak_name);
   498           val fs_inst  = PureThy.get_thm thy (Name ("fs_"^ak_name^"_inst"));
   496           val fs_inst  = PureThy.get_thm thy (Name ("fs_"^ak_name^"_inst"));
   499           fun fs_proof thm = EVERY [ClassPackage.intro_classes_tac [], rtac (thm RS fs1) 1];      
   497           fun fs_proof thm = EVERY [ClassPackage.intro_classes_tac [], rtac (thm RS fs1) 1];
   500 
   498 
   501           val fs_thm_unit  = fs_unit_inst;
   499           val fs_thm_unit  = fs_unit_inst;
   502           val fs_thm_prod  = fs_inst RS (fs_inst RS fs_prod_inst);
   500           val fs_thm_prod  = fs_inst RS (fs_inst RS fs_prod_inst);
   503           val fs_thm_nprod = fs_inst RS (fs_inst RS fs_nprod_inst);
   501           val fs_thm_nprod = fs_inst RS (fs_inst RS fs_nprod_inst);
   504           val fs_thm_list  = fs_inst RS fs_list_inst;
   502           val fs_thm_list  = fs_inst RS fs_list_inst;
   505           val fs_thm_optn  = fs_inst RS fs_option_inst;
   503           val fs_thm_optn  = fs_inst RS fs_option_inst;
   506         in 
   504         in 
   507          thy 
   505          thy
   508          |> AxClass.prove_arity ("Product_Type.unit",[],[cls_name]) (fs_proof fs_thm_unit) 
   506          |> AxClass.prove_arity ("Product_Type.unit",[],[cls_name]) (fs_proof fs_thm_unit) 
   509          |> AxClass.prove_arity ("*",[[cls_name],[cls_name]],[cls_name]) (fs_proof fs_thm_prod) 
   507          |> AxClass.prove_arity ("*",[[cls_name],[cls_name]],[cls_name]) (fs_proof fs_thm_prod) 
   510          |> AxClass.prove_arity ("Nominal.nprod",[[cls_name],[cls_name]],[cls_name]) 
   508          |> AxClass.prove_arity ("Nominal.nprod",[[cls_name],[cls_name]],[cls_name]) 
   511                                      (fs_proof fs_thm_nprod) 
   509                                      (fs_proof fs_thm_nprod) 
   512          |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (fs_proof fs_thm_list)
   510          |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (fs_proof fs_thm_list)
   513          |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (fs_proof fs_thm_optn)
   511          |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (fs_proof fs_thm_optn)
   514         end) ak_names thy20; 
   512         end) ak_names thy20;
   515 
   513 
   516        (*<<<<<<<  cp_<ak>_<ai> class instances  >>>>>>>*)
   514        (********  cp_<ak>_<ai> class instances  ********)
   517        (*==============================================*)
   515        (*==============================================*)
   518        (* abbreviations for some lemmas *)
   516        (* abbreviations for some lemmas *)
   519        val cp1             = thm "cp1";
   517        val cp1             = thm "cp1";
   520        val cp_unit_inst    = thm "cp_unit_inst";
   518        val cp_unit_inst    = thm "cp_unit_inst";
   521        val cp_bool_inst    = thm "cp_bool_inst";
   519        val cp_bool_inst    = thm "cp_bool_inst";
   523        val cp_list_inst    = thm "cp_list_inst";
   521        val cp_list_inst    = thm "cp_list_inst";
   524        val cp_fun_inst     = thm "cp_fun_inst";
   522        val cp_fun_inst     = thm "cp_fun_inst";
   525        val cp_option_inst  = thm "cp_option_inst";
   523        val cp_option_inst  = thm "cp_option_inst";
   526        val cp_noption_inst = thm "cp_noption_inst";
   524        val cp_noption_inst = thm "cp_noption_inst";
   527        val pt_perm_compose = thm "pt_perm_compose";
   525        val pt_perm_compose = thm "pt_perm_compose";
   528        
   526 
   529        val dj_pp_forget    = thm "dj_perm_perm_forget";
   527        val dj_pp_forget    = thm "dj_perm_perm_forget";
   530 
   528 
   531        (* shows that <aj> is an instance of cp_<ak>_<ai>  *)
   529        (* shows that <aj> is an instance of cp_<ak>_<ai>  *)
   532        (* for every  <ak>/<ai>-combination                *)
   530        (* for every  <ak>/<ai>-combination                *)
   533        val thy25 = fold (fn ak_name => fn thy => 
   531        val thy25 = fold (fn ak_name => fn thy =>
   534 	 fold (fn ak_name' => fn thy' => 
   532          fold (fn ak_name' => fn thy' =>
   535           fold (fn ak_name'' => fn thy'' => 
   533           fold (fn ak_name'' => fn thy'' =>
   536             let
   534             let
   537               val name =  Sign.full_name (sign_of thy'') ak_name;
   535               val name =  Sign.full_name (sign_of thy'') ak_name;
   538               val cls_name = Sign.full_name (sign_of thy'') ("cp_"^ak_name'^"_"^ak_name'');
   536               val cls_name = Sign.full_name (sign_of thy'') ("cp_"^ak_name'^"_"^ak_name'');
   539               val proof =
   537               val proof =
   540                 (if (ak_name'=ak_name'') then 
   538                 (if (ak_name'=ak_name'') then 
   541 		  (let
   539                   (let
   542                     val pt_inst  = PureThy.get_thm thy'' (Name ("pt_"^ak_name''^"_inst"));
   540                     val pt_inst  = PureThy.get_thm thy'' (Name ("pt_"^ak_name''^"_inst"));
   543 		    val at_inst  = PureThy.get_thm thy'' (Name ("at_"^ak_name''^"_inst"));
   541                     val at_inst  = PureThy.get_thm thy'' (Name ("at_"^ak_name''^"_inst"));
   544                   in 
   542                   in
   545 		   EVERY [ClassPackage.intro_classes_tac [], 
   543 		   EVERY [ClassPackage.intro_classes_tac [],
   546                           rtac (at_inst RS (pt_inst RS pt_perm_compose)) 1]
   544                           rtac (at_inst RS (pt_inst RS pt_perm_compose)) 1]
   547                   end)
   545                   end)
   548 		else
   546 		else
   549 		  (let 
   547 		  (let
   550                      val dj_inst  = PureThy.get_thm thy'' (Name ("dj_"^ak_name''^"_"^ak_name'));
   548                      val dj_inst  = PureThy.get_thm thy'' (Name ("dj_"^ak_name''^"_"^ak_name'));
   551 		     val simp_s = HOL_basic_ss addsimps 
   549 		     val simp_s = HOL_basic_ss addsimps
   552                                         ((dj_inst RS dj_pp_forget)::
   550                                         ((dj_inst RS dj_pp_forget)::
   553                                          (PureThy.get_thmss thy'' 
   551                                          (PureThy.get_thmss thy''
   554 					   [Name (ak_name' ^"_prm_"^ak_name^"_def"),
   552                                            [Name (ak_name' ^"_prm_"^ak_name^"_def"),
   555                                             Name (ak_name''^"_prm_"^ak_name^"_def")]));  
   553                                             Name (ak_name''^"_prm_"^ak_name^"_def")]));
   556 		  in 
   554                   in
   557                     EVERY [ClassPackage.intro_classes_tac [], simp_tac simp_s 1]
   555                     EVERY [ClassPackage.intro_classes_tac [], simp_tac simp_s 1]
   558                   end))
   556                   end))
   559 	      in
   557               in
   560                 AxClass.prove_arity (name,[],[cls_name]) proof thy''
   558                 AxClass.prove_arity (name,[],[cls_name]) proof thy''
   561 	      end) ak_names thy') ak_names thy) ak_names thy24;
   559               end) ak_names thy') ak_names thy) ak_names thy24;
   562       
   560 
   563        (* shows that                                                    *) 
   561        (* shows that                                                    *) 
   564        (*      units                                                    *) 
   562        (*      units                                                    *) 
   565        (*      products                                                 *)
   563        (*      products                                                 *)
   566        (*      lists                                                    *)
   564        (*      lists                                                    *)
   567        (*      functions                                                *)
   565        (*      functions                                                *)
   574             val cls_name = Sign.full_name (sign_of thy') ("cp_"^ak_name^"_"^ak_name');
   572             val cls_name = Sign.full_name (sign_of thy') ("cp_"^ak_name^"_"^ak_name');
   575             val cp_inst  = PureThy.get_thm thy' (Name ("cp_"^ak_name^"_"^ak_name'^"_inst"));
   573             val cp_inst  = PureThy.get_thm thy' (Name ("cp_"^ak_name^"_"^ak_name'^"_inst"));
   576             val pt_inst  = PureThy.get_thm thy' (Name ("pt_"^ak_name^"_inst"));
   574             val pt_inst  = PureThy.get_thm thy' (Name ("pt_"^ak_name^"_inst"));
   577             val at_inst  = PureThy.get_thm thy' (Name ("at_"^ak_name^"_inst"));
   575             val at_inst  = PureThy.get_thm thy' (Name ("at_"^ak_name^"_inst"));
   578 
   576 
   579             fun cp_proof thm  = EVERY [ClassPackage.intro_classes_tac [],rtac (thm RS cp1) 1];     
   577             fun cp_proof thm  = EVERY [ClassPackage.intro_classes_tac [],rtac (thm RS cp1) 1];
   580 	  
   578 	  
   581             val cp_thm_unit = cp_unit_inst;
   579             val cp_thm_unit = cp_unit_inst;
   582             val cp_thm_prod = cp_inst RS (cp_inst RS cp_prod_inst);
   580             val cp_thm_prod = cp_inst RS (cp_inst RS cp_prod_inst);
   583             val cp_thm_list = cp_inst RS cp_list_inst;
   581             val cp_thm_list = cp_inst RS cp_list_inst;
   584             val cp_thm_fun  = at_inst RS (pt_inst RS (cp_inst RS (cp_inst RS cp_fun_inst)));
   582             val cp_thm_fun  = at_inst RS (pt_inst RS (cp_inst RS (cp_inst RS cp_fun_inst)));
   591          |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (cp_proof cp_thm_list)
   589          |> AxClass.prove_arity ("List.list",[[cls_name]],[cls_name]) (cp_proof cp_thm_list)
   592          |> AxClass.prove_arity ("fun",[[cls_name],[cls_name]],[cls_name]) (cp_proof cp_thm_fun)
   590          |> AxClass.prove_arity ("fun",[[cls_name],[cls_name]],[cls_name]) (cp_proof cp_thm_fun)
   593          |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (cp_proof cp_thm_optn)
   591          |> AxClass.prove_arity ("Datatype.option",[[cls_name]],[cls_name]) (cp_proof cp_thm_optn)
   594          |> AxClass.prove_arity ("Nominal.noption",[[cls_name]],[cls_name]) (cp_proof cp_thm_noptn)
   592          |> AxClass.prove_arity ("Nominal.noption",[[cls_name]],[cls_name]) (cp_proof cp_thm_noptn)
   595         end) ak_names thy) ak_names thy25;
   593         end) ak_names thy) ak_names thy25;
   596        
   594 
   597      (* show that discrete nominal types are permutation types, finitely     *) 
   595      (* show that discrete nominal types are permutation types, finitely     *)
   598      (* supported and have the commutation property                          *)
   596      (* supported and have the commutation property                          *)
   599      (* discrete types have a permutation operation defined as pi o x = x;   *)
   597      (* discrete types have a permutation operation defined as pi o x = x;   *)
   600      (* which renders the proofs to be simple "simp_all"-proofs.             *)            
   598      (* which renders the proofs to be simple "simp_all"-proofs.             *)
   601      val thy32 =
   599      val thy32 =
   602         let 
   600         let
   603 	  fun discrete_pt_inst discrete_ty defn = 
   601 	  fun discrete_pt_inst discrete_ty defn =
   604 	     fold (fn ak_name => fn thy =>
   602 	     fold (fn ak_name => fn thy =>
   605 	     let
   603 	     let
   606 	       val qu_class = Sign.full_name (sign_of thy) ("pt_"^ak_name);
   604 	       val qu_class = Sign.full_name (sign_of thy) ("pt_"^ak_name);
   607 	       val simp_s = HOL_basic_ss addsimps [defn];
   605 	       val simp_s = HOL_basic_ss addsimps [defn];
   608                val proof = EVERY [ClassPackage.intro_classes_tac [], REPEAT (asm_simp_tac simp_s 1)];      
   606                val proof = EVERY [ClassPackage.intro_classes_tac [], REPEAT (asm_simp_tac simp_s 1)];
   609              in  
   607              in 
   610 	       AxClass.prove_arity (discrete_ty,[],[qu_class]) proof thy
   608 	       AxClass.prove_arity (discrete_ty,[],[qu_class]) proof thy
   611              end) ak_names;
   609              end) ak_names;
   612 
   610 
   613           fun discrete_fs_inst discrete_ty defn = 
   611           fun discrete_fs_inst discrete_ty defn = 
   614 	     fold (fn ak_name => fn thy =>
   612 	     fold (fn ak_name => fn thy =>
   615 	     let
   613 	     let
   616 	       val qu_class = Sign.full_name (sign_of thy) ("fs_"^ak_name);
   614 	       val qu_class = Sign.full_name (sign_of thy) ("fs_"^ak_name);
   617 	       val supp_def = thm "Nominal.supp_def";
   615 	       val supp_def = thm "Nominal.supp_def";
   618                val simp_s = HOL_ss addsimps [supp_def,Collect_const,Finites.emptyI,defn];
   616                val simp_s = HOL_ss addsimps [supp_def,Collect_const,Finites.emptyI,defn];
   619                val proof = EVERY [ClassPackage.intro_classes_tac [], asm_simp_tac simp_s 1];      
   617                val proof = EVERY [ClassPackage.intro_classes_tac [], asm_simp_tac simp_s 1];
   620              in  
   618              in 
   621 	       AxClass.prove_arity (discrete_ty,[],[qu_class]) proof thy
   619 	       AxClass.prove_arity (discrete_ty,[],[qu_class]) proof thy
   622              end) ak_names;  
   620              end) ak_names;
   623 
   621 
   624           fun discrete_cp_inst discrete_ty defn = 
   622           fun discrete_cp_inst discrete_ty defn = 
   625 	     fold (fn ak_name' => (fold (fn ak_name => fn thy =>
   623 	     fold (fn ak_name' => (fold (fn ak_name => fn thy =>
   626 	     let
   624 	     let
   627 	       val qu_class = Sign.full_name (sign_of thy) ("cp_"^ak_name^"_"^ak_name');
   625 	       val qu_class = Sign.full_name (sign_of thy) ("cp_"^ak_name^"_"^ak_name');
   628 	       val supp_def = thm "Nominal.supp_def";
   626 	       val supp_def = thm "Nominal.supp_def";
   629                val simp_s = HOL_ss addsimps [defn];
   627                val simp_s = HOL_ss addsimps [defn];
   630                val proof = EVERY [ClassPackage.intro_classes_tac [], asm_simp_tac simp_s 1];      
   628                val proof = EVERY [ClassPackage.intro_classes_tac [], asm_simp_tac simp_s 1];
   631              in  
   629              in
   632 	       AxClass.prove_arity (discrete_ty,[],[qu_class]) proof thy
   630 	       AxClass.prove_arity (discrete_ty,[],[qu_class]) proof thy
   633              end) ak_names)) ak_names;  
   631              end) ak_names)) ak_names;
   634           
   632 
   635         in
   633         in
   636          thy26
   634          thy26
   637          |> discrete_pt_inst "nat"  (thm "perm_nat_def")
   635          |> discrete_pt_inst "nat"  (thm "perm_nat_def")
   638          |> discrete_fs_inst "nat"  (thm "perm_nat_def") 
   636          |> discrete_fs_inst "nat"  (thm "perm_nat_def") 
   639          |> discrete_cp_inst "nat"  (thm "perm_nat_def") 
   637          |> discrete_cp_inst "nat"  (thm "perm_nat_def") 
   646          |> discrete_pt_inst "List.char" (thm "perm_char_def")
   644          |> discrete_pt_inst "List.char" (thm "perm_char_def")
   647          |> discrete_fs_inst "List.char" (thm "perm_char_def")
   645          |> discrete_fs_inst "List.char" (thm "perm_char_def")
   648          |> discrete_cp_inst "List.char" (thm "perm_char_def")
   646          |> discrete_cp_inst "List.char" (thm "perm_char_def")
   649         end;
   647         end;
   650 
   648 
   651  
   649 
   652        (* abbreviations for some lemmas *)
   650        (* abbreviations for some lemmas *)
   653        (*===============================*)
   651        (*===============================*)
   654        val abs_fun_pi          = thm "Nominal.abs_fun_pi";
   652        val abs_fun_pi          = thm "Nominal.abs_fun_pi";
   655        val abs_fun_pi_ineq     = thm "Nominal.abs_fun_pi_ineq";
   653        val abs_fun_pi_ineq     = thm "Nominal.abs_fun_pi_ineq";
   656        val abs_fun_eq          = thm "Nominal.abs_fun_eq";
   654        val abs_fun_eq          = thm "Nominal.abs_fun_eq";
   683        val fresh_eqvt          = thm "Nominal.pt_fresh_eqvt";
   681        val fresh_eqvt          = thm "Nominal.pt_fresh_eqvt";
   684        val all_eqvt            = thm "Nominal.pt_all_eqvt";
   682        val all_eqvt            = thm "Nominal.pt_all_eqvt";
   685        val pt_pi_rev           = thm "Nominal.pt_pi_rev";
   683        val pt_pi_rev           = thm "Nominal.pt_pi_rev";
   686        val pt_rev_pi           = thm "Nominal.pt_rev_pi";
   684        val pt_rev_pi           = thm "Nominal.pt_rev_pi";
   687        val at_exists_fresh     = thm "Nominal.at_exists_fresh";
   685        val at_exists_fresh     = thm "Nominal.at_exists_fresh";
   688   
   686 
   689 
   687 
   690        (* Now we collect and instantiate some lemmas w.r.t. all atom      *)
   688        (* Now we collect and instantiate some lemmas w.r.t. all atom      *)
   691        (* types; this allows for example to use abs_perm (which is a      *)
   689        (* types; this allows for example to use abs_perm (which is a      *)
   692        (* collection of theorems) instead of thm abs_fun_pi with explicit *)
   690        (* collection of theorems) instead of thm abs_fun_pi with explicit *)
   693        (* instantiations.                                                 *)
   691        (* instantiations.                                                 *)
   694        val (_,thy33) = 
   692        val (_, thy33) =
   695 	 let 
   693          let
   696              
       
   697 
   694 
   698              (* takes a theorem thm and a list of theorems [t1,..,tn]            *)
   695              (* takes a theorem thm and a list of theorems [t1,..,tn]            *)
   699              (* produces a list of theorems of the form [t1 RS thm,..,tn RS thm] *) 
   696              (* produces a list of theorems of the form [t1 RS thm,..,tn RS thm] *) 
   700              fun instR thm thms = map (fn ti => ti RS thm) thms;
   697              fun instR thm thms = map (fn ti => ti RS thm) thms;
   701 
   698 
   731 	       let fun djs_fun (ak1,ak2) = 
   728 	       let fun djs_fun (ak1,ak2) = 
   732 		     if ak1=ak2 then NONE else SOME(PureThy.get_thm thy32 (Name ("dj_"^ak2^"_"^ak1)))
   729 		     if ak1=ak2 then NONE else SOME(PureThy.get_thm thy32 (Name ("dj_"^ak2^"_"^ak1)))
   733 	       in List.mapPartial I (map djs_fun (Library.product ak_names ak_names)) end;
   730 	       in List.mapPartial I (map djs_fun (Library.product ak_names ak_names)) end;
   734              (* list of all fs_inst-theorems *)
   731              (* list of all fs_inst-theorems *)
   735              val fss = map (fn ak => PureThy.get_thm thy32 (Name ("fs_"^ak^"_inst"))) ak_names
   732              val fss = map (fn ak => PureThy.get_thm thy32 (Name ("fs_"^ak^"_inst"))) ak_names
   736               
   733 
   737              fun inst_pt thms = Library.flat (map (fn ti => instR ti pts) thms); 
   734              fun inst_pt thms = Library.flat (map (fn ti => instR ti pts) thms);
   738              fun inst_at thms = Library.flat (map (fn ti => instR ti ats) thms);               
   735              fun inst_at thms = Library.flat (map (fn ti => instR ti ats) thms);
   739              fun inst_fs thms = Library.flat (map (fn ti => instR ti fss) thms);
   736              fun inst_fs thms = Library.flat (map (fn ti => instR ti fss) thms);
   740              fun inst_cp thms cps = Library.flat (inst_mult thms cps); 
   737              fun inst_cp thms cps = Library.flat (inst_mult thms cps);
   741 	     fun inst_pt_at thms = inst_zip ats (inst_pt thms);			
   738 	     fun inst_pt_at thms = inst_zip ats (inst_pt thms);
   742              fun inst_dj thms = Library.flat (map (fn ti => instR ti djs) thms);  
   739              fun inst_dj thms = Library.flat (map (fn ti => instR ti djs) thms);
   743 	     fun inst_pt_pt_at_cp thms = inst_cp (inst_zip ats (inst_zip pts (inst_pt thms))) cps;
   740 	     fun inst_pt_pt_at_cp thms = inst_cp (inst_zip ats (inst_zip pts (inst_pt thms))) cps;
   744              fun inst_pt_at_fs thms = inst_zip (inst_fs [fs1]) (inst_zip ats (inst_pt thms));
   741              fun inst_pt_at_fs thms = inst_zip (inst_fs [fs1]) (inst_zip ats (inst_pt thms));
   745 	     fun inst_pt_pt_at_cp thms = 
   742 	     fun inst_pt_pt_at_cp thms =
   746 		 let val i_pt_pt_at = inst_zip ats (inst_zip pts (inst_pt thms));
   743 		 let val i_pt_pt_at = inst_zip ats (inst_zip pts (inst_pt thms));
   747                      val i_pt_pt_at_cp = inst_cp i_pt_pt_at cps';
   744                      val i_pt_pt_at_cp = inst_cp i_pt_pt_at cps';
   748 		 in i_pt_pt_at_cp end;
   745 		 in i_pt_pt_at_cp end;
   749              fun inst_pt_pt_at_cp_dj thms = inst_zip djs (inst_pt_pt_at_cp thms);
   746              fun inst_pt_pt_at_cp_dj thms = inst_zip djs (inst_pt_pt_at_cp thms);
   750            in
   747            in