Nominal/NewParser.thy
changeset 2431 331873ebc5cd
parent 2430 a746d49b0240
child 2434 92dc6cfa3a95
equal deleted inserted replaced
2430:a746d49b0240 2431:331873ebc5cd
     3         "../Nominal-General/Nominal2_Eqvt" 
     3         "../Nominal-General/Nominal2_Eqvt" 
     4         "../Nominal-General/Nominal2_Supp" 
     4         "../Nominal-General/Nominal2_Supp" 
     5         "Perm" "Tacs" "Equivp"
     5         "Perm" "Tacs" "Equivp"
     6 begin
     6 begin
     7 
     7 
     8 (* TODO
       
     9 
       
    10   we need to also export a cases-rule for nominal datatypes
       
    11   size function
       
    12 *)
       
    13 
     8 
    14 section{* Interface for nominal_datatype *}
     9 section{* Interface for nominal_datatype *}
    15 
    10 
    16 ML {*
    11 ML {*
    17 (* attributes *)
    12 (* attributes *)
    33 fun get_cnstr_strs dts =
    28 fun get_cnstr_strs dts =
    34   map (fn (bn, _, _) => Binding.name_of bn) (flat (get_cnstrs dts))
    29   map (fn (bn, _, _) => Binding.name_of bn) (flat (get_cnstrs dts))
    35 
    30 
    36 fun get_bn_fun_strs bn_funs =
    31 fun get_bn_fun_strs bn_funs =
    37   map (fn (bn_fun, _, _) => Binding.name_of bn_fun) bn_funs
    32   map (fn (bn_fun, _, _) => Binding.name_of bn_fun) bn_funs
    38 *}
       
    39 
       
    40 
       
    41 ML {*
       
    42 fun add_datatype_wrapper dt_names dts =
       
    43 let
       
    44   val conf = Datatype.default_config
       
    45 in
       
    46   Local_Theory.theory_result (Datatype.add_datatype conf dt_names dts)
       
    47 end
       
    48 *}
    33 *}
    49 
    34 
    50 
    35 
    51 text {* Infrastructure for adding "_raw" to types and terms *}
    36 text {* Infrastructure for adding "_raw" to types and terms *}
    52 
    37 
   139   aux t
   124   aux t
   140 end  
   125 end  
   141 *}
   126 *}
   142 
   127 
   143 ML {*
   128 ML {*
       
   129 (** definition of the raw binding functions **)
       
   130 
       
   131 (* TODO: needs cleaning *)
   144 fun find [] _ = error ("cannot find element")
   132 fun find [] _ = error ("cannot find element")
   145   | find ((x, z)::xs) y = if (Long_Name.base_name x) = y then z else find xs y
   133   | find ((x, z)::xs) y = if (Long_Name.base_name x) = y then z else find xs y
   146 *}
   134 
   147 
       
   148 ML {*
       
   149 fun prep_bn_info lthy dt_names dts eqs = 
   135 fun prep_bn_info lthy dt_names dts eqs = 
   150 let
   136 let
   151   fun aux eq = 
   137   fun aux eq = 
   152   let
   138   let
   153     val (lhs, rhs) = eq
   139     val (lhs, rhs) = eq
   180   (*val _ = tracing ("map eqs\n" ^ @{make_string} (map aux2 eqs))*)
   166   (*val _ = tracing ("map eqs\n" ^ @{make_string} (map aux2 eqs))*)
   181   (*val _ = tracing ("ordered'\n" ^ @{make_string} ordered')*)
   167   (*val _ = tracing ("ordered'\n" ^ @{make_string} ordered')*)
   182 in
   168 in
   183   ordered'
   169   ordered'
   184 end
   170 end
   185 *}
   171 
   186 
   172 
   187 ML {*
       
   188 fun define_raw_dts dts bn_funs bn_eqs binds lthy =
       
   189 let
       
   190   val thy = ProofContext.theory_of lthy
       
   191   val thy_name = Context.theory_name thy
       
   192 
       
   193   val dt_names = map (fn (_, s, _, _) => Binding.name_of s) dts
       
   194   val dt_full_names = map (Long_Name.qualify thy_name) dt_names 
       
   195   val dt_full_names' = add_raws dt_full_names
       
   196   val dts_env = dt_full_names ~~ dt_full_names'
       
   197 
       
   198   val cnstrs = get_cnstr_strs dts
       
   199   val cnstrs_ty = get_typed_cnstrs dts
       
   200   val cnstrs_full_names = map (Long_Name.qualify thy_name) cnstrs
       
   201   val cnstrs_full_names' = map (fn (x, y) => Long_Name.qualify thy_name 
       
   202     (Long_Name.qualify (add_raw x) (add_raw y))) cnstrs_ty
       
   203   val cnstrs_env = cnstrs_full_names ~~ cnstrs_full_names'
       
   204 
       
   205   val bn_fun_strs = get_bn_fun_strs bn_funs
       
   206   val bn_fun_strs' = add_raws bn_fun_strs
       
   207   val bn_fun_env = bn_fun_strs ~~ bn_fun_strs'
       
   208   val bn_fun_full_env = map (pairself (Long_Name.qualify thy_name)) 
       
   209     (bn_fun_strs ~~ bn_fun_strs')
       
   210   
       
   211   val (raw_dt_names, raw_dts) = rawify_dts dt_names dts dts_env
       
   212   val (raw_bn_funs, raw_bn_eqs) = rawify_bn_funs dts_env cnstrs_env bn_fun_env bn_funs bn_eqs 
       
   213   val raw_bclauses = rawify_bclauses dts_env cnstrs_env bn_fun_full_env binds 
       
   214 
       
   215   val (raw_dt_full_names, lthy1) = 
       
   216     add_datatype_wrapper raw_dt_names raw_dts lthy
       
   217 in
       
   218   (raw_dt_full_names, raw_dts, raw_bclauses, raw_bn_funs, raw_bn_eqs, lthy1)
       
   219 end
       
   220 *}
       
   221 
       
   222 ML {*
       
   223 (* should be in nominal_dt_rawfuns *)
       
   224 fun define_raw_bns dt_names dts raw_bn_funs raw_bn_eqs constr_thms size_thms lthy =
   173 fun define_raw_bns dt_names dts raw_bn_funs raw_bn_eqs constr_thms size_thms lthy =
   225   if null raw_bn_funs 
   174   if null raw_bn_funs 
   226   then ([], [], [], [], lthy)
   175   then ([], [], [], [], lthy)
   227   else 
   176   else 
   228     let
   177     let
   240     in
   189     in
   241       (fs, raw_bn_eqs, raw_bn_info, raw_bn_induct, lthy2)
   190       (fs, raw_bn_eqs, raw_bn_info, raw_bn_induct, lthy2)
   242     end
   191     end
   243 *}
   192 *}
   244 
   193 
       
   194 ML {*
       
   195 fun define_raw_dts dts bn_funs bn_eqs binds lthy =
       
   196 let
       
   197   val thy = Local_Theory.exit_global lthy
       
   198   val thy_name = Context.theory_name thy
       
   199 
       
   200   val dt_names = map (fn (_, s, _, _) => Binding.name_of s) dts
       
   201   val dt_full_names = map (Long_Name.qualify thy_name) dt_names 
       
   202   val dt_full_names' = add_raws dt_full_names
       
   203   val dts_env = dt_full_names ~~ dt_full_names'
       
   204 
       
   205   val cnstrs = get_cnstr_strs dts
       
   206   val cnstrs_ty = get_typed_cnstrs dts
       
   207   val cnstrs_full_names = map (Long_Name.qualify thy_name) cnstrs
       
   208   val cnstrs_full_names' = map (fn (x, y) => Long_Name.qualify thy_name 
       
   209     (Long_Name.qualify (add_raw x) (add_raw y))) cnstrs_ty
       
   210   val cnstrs_env = cnstrs_full_names ~~ cnstrs_full_names'
       
   211 
       
   212   val bn_fun_strs = get_bn_fun_strs bn_funs
       
   213   val bn_fun_strs' = add_raws bn_fun_strs
       
   214   val bn_fun_env = bn_fun_strs ~~ bn_fun_strs'
       
   215   val bn_fun_full_env = map (pairself (Long_Name.qualify thy_name)) 
       
   216     (bn_fun_strs ~~ bn_fun_strs')
       
   217   
       
   218   val (raw_dt_names, raw_dts) = rawify_dts dt_names dts dts_env
       
   219   val (raw_bn_funs, raw_bn_eqs) = rawify_bn_funs dts_env cnstrs_env bn_fun_env bn_funs bn_eqs 
       
   220   val raw_bclauses = rawify_bclauses dts_env cnstrs_env bn_fun_full_env binds 
       
   221 
       
   222   val (raw_dt_full_names, thy1) = 
       
   223     Datatype.add_datatype Datatype.default_config raw_dt_names raw_dts thy
       
   224 
       
   225   val lthy1 = Named_Target.theory_init thy1
       
   226 in
       
   227   (raw_dt_full_names, raw_dts, raw_bclauses, raw_bn_funs, raw_bn_eqs, lthy1)
       
   228 end
       
   229 *}
       
   230 
   245 
   231 
   246 ML {*
   232 ML {*
   247 (* for testing porposes - to exit the procedure early *)
   233 (* for testing porposes - to exit the procedure early *)
   248 exception TEST of Proof.context
   234 exception TEST of Proof.context
   249 
   235 
   253 *}
   239 *}
   254 
   240 
   255 setup STEPS_setup
   241 setup STEPS_setup
   256 
   242 
   257 ML {*
   243 ML {*
   258 fun nominal_datatype2 dts bn_funs bn_eqs bclauses lthy =
   244 fun nominal_datatype2 thm_name dts bn_funs bn_eqs bclauses lthy =
   259 let
   245 let
   260   (* definition of the raw datatypes *)
   246   (* definition of the raw datatypes *)
   261   val _ = warning "Definition of raw datatypes";
   247   val _ = warning "Definition of raw datatypes";
   262   val (raw_dt_names, raw_dts, raw_bclauses, raw_bn_funs, raw_bn_eqs, lthy0) =
   248   val (raw_dt_names, raw_dts, raw_bclauses, raw_bn_funs, raw_bn_eqs, lthy0) =
   263     if get_STEPS lthy > 0 
   249     if get_STEPS lthy > 0 
   267   val dtinfo = Datatype.the_info (ProofContext.theory_of lthy0) (hd raw_dt_names)
   253   val dtinfo = Datatype.the_info (ProofContext.theory_of lthy0) (hd raw_dt_names)
   268   val {descr, sorts, ...} = dtinfo
   254   val {descr, sorts, ...} = dtinfo
   269 
   255 
   270   val raw_tys = all_dtyps descr sorts
   256   val raw_tys = all_dtyps descr sorts
   271   val raw_full_ty_names = map (fst o dest_Type) raw_tys
   257   val raw_full_ty_names = map (fst o dest_Type) raw_tys
   272   
   258   val tvs = hd raw_tys
       
   259     |> snd o dest_Type
       
   260     |> map dest_TFree  
       
   261 
   273   val dtinfos = map (Datatype.the_info (ProofContext.theory_of lthy0)) raw_full_ty_names  
   262   val dtinfos = map (Datatype.the_info (ProofContext.theory_of lthy0)) raw_full_ty_names  
   274  
   263  
   275   val raw_cns_info = all_dtyp_constrs_types descr sorts
   264   val raw_cns_info = all_dtyp_constrs_types descr sorts
   276   val raw_constrs = flat (map (map (fn (c, _, _, _) => c)) raw_cns_info)
   265   val raw_constrs = flat (map (map (fn (c, _, _, _) => c)) raw_cns_info)
   277 
   266 
   287   
   276   
   288   (* definitions of raw permutations by primitive recursion *)
   277   (* definitions of raw permutations by primitive recursion *)
   289   val _ = warning "Definition of raw permutations";
   278   val _ = warning "Definition of raw permutations";
   290   val ((raw_perm_funs, raw_perm_simps, raw_perm_laws), lthy2a) =
   279   val ((raw_perm_funs, raw_perm_simps, raw_perm_laws), lthy2a) =
   291     if get_STEPS lthy0 > 1 
   280     if get_STEPS lthy0 > 1 
   292     then define_raw_perms raw_full_ty_names raw_tys raw_constrs raw_induct_thm lthy0
   281     then define_raw_perms raw_full_ty_names raw_tys tvs raw_constrs raw_induct_thm lthy0
   293     else raise TEST lthy0
   282     else raise TEST lthy0
   294  
   283  
   295   (* noting the raw permutations as eqvt theorems *)
   284   (* noting the raw permutations as eqvt theorems *)
   296   val (_, lthy3) = Local_Theory.note ((Binding.empty, [eqvt_attrib]), raw_perm_simps) lthy2a
   285   val (_, lthy3) = Local_Theory.note ((Binding.empty, [eqvt_attrib]), raw_perm_simps) lthy2a
   297 
   286 
   448 
   437 
   449   val qalpha_bns_descr = 
   438   val qalpha_bns_descr = 
   450     map2 (fn (b, _, _) => fn t => ("alpha_" ^ Name.of_binding b, t, NoSyn)) bn_funs  alpha_bn_trms
   439     map2 (fn (b, _, _) => fn t => ("alpha_" ^ Name.of_binding b, t, NoSyn)) bn_funs  alpha_bn_trms
   451 
   440 
   452   val qperm_descr =
   441   val qperm_descr =
   453     map2 (fn n => fn t => ("permute_" ^ n, t, NoSyn)) qty_names raw_perm_funs
   442     map2 (fn n => fn t => ("permute_" ^ n, Type.legacy_freeze t, NoSyn)) qty_names raw_perm_funs
   454 
   443 
   455   val qsize_descr =
   444   val qsize_descr =
   456     map2 (fn n => fn t => ("size_" ^ n, t, NoSyn)) qty_names raw_size_trms
   445     map2 (fn n => fn t => ("size_" ^ n, t, NoSyn)) qty_names raw_size_trms
   457 
   446 
   458   val (((((qconstrs_info, qbns_info), qfvs_info), qfv_bns_info), qalpha_bns_info), lthy8) = 
   447   val (((((qconstrs_info, qbns_info), qfvs_info), qfv_bns_info), qalpha_bns_info), lthy8) = 
   467     else raise TEST lthy7
   456     else raise TEST lthy7
   468 
   457 
   469   (* definition of the quotient permfunctions and pt-class *)
   458   (* definition of the quotient permfunctions and pt-class *)
   470   val lthy9 = 
   459   val lthy9 = 
   471     if get_STEPS lthy > 18
   460     if get_STEPS lthy > 18
   472     then define_qperms qtys qty_full_names qperm_descr raw_perm_laws lthy8 
   461     then define_qperms qtys qty_full_names tvs qperm_descr raw_perm_laws lthy8 
   473     else raise TEST lthy8
   462     else raise TEST lthy8
   474   
   463   
   475   val lthy9a = 
   464   val lthy9a = 
   476     if get_STEPS lthy > 19
   465     if get_STEPS lthy > 19
   477     then define_qsizes qtys qty_full_names qsize_descr lthy9
   466     then define_qsizes qtys qty_full_names tvs qsize_descr lthy9
   478     else raise TEST lthy9
   467     else raise TEST lthy9
   479 
   468 
   480   val qconstrs = map #qconst qconstrs_info
   469   val qconstrs = map #qconst qconstrs_info
   481   val qbns = map #qconst qbns_info
   470   val qbns = map #qconst qbns_info
   482   val qfvs = map #qconst qfvs_info
   471   val qfvs = map #qconst qfvs_info
   483   val qfv_bns = map #qconst qfv_bns_info
   472   val qfv_bns = map #qconst qfv_bns_info
   484   val qalpha_bns = map #qconst qalpha_bns_info
   473   val qalpha_bns = map #qconst qalpha_bns_info
   485 
       
   486   
   474   
   487   (* temporary theorem bindings *)
   475   (* temporary theorem bindings *)
   488 
       
   489   val (_, lthy9') = lthy9a
   476   val (_, lthy9') = lthy9a
   490      |> Local_Theory.note ((@{binding "distinct"}, []), alpha_distincts) 
   477      |> Local_Theory.note ((@{binding "distinct"}, []), alpha_distincts) 
   491      ||>> Local_Theory.note ((@{binding "eq_iff"}, []), alpha_eq_iff)
   478      ||>> Local_Theory.note ((@{binding "eq_iff"}, []), alpha_eq_iff)
   492      ||>> Local_Theory.note ((@{binding "eq_iff_simps"}, []), alpha_eq_iff_simps) 
   479      ||>> Local_Theory.note ((@{binding "eq_iff_simps"}, []), alpha_eq_iff_simps) 
   493      ||>> Local_Theory.note ((@{binding "fv_defs"}, []), raw_fv_defs) 
   480      ||>> Local_Theory.note ((@{binding "fv_defs"}, []), raw_fv_defs) 
   513   val _ = warning "Proving respects";
   500   val _ = warning "Proving respects";
   514 
   501 
   515   val bn_nos = map (fn (_, i, _) => i) raw_bn_info;
   502   val bn_nos = map (fn (_, i, _) => i) raw_bn_info;
   516   val bns = raw_bns ~~ bn_nos;
   503   val bns = raw_bns ~~ bn_nos;
   517 
   504 
   518   val bns_rsp_pre' = build_fvbv_rsps alpha_trms alpha_induct raw_bn_defs (map fst bns) lthy8;
   505   val bns_rsp_pre' = build_fvbv_rsps alpha_trms alpha_induct raw_bn_defs (map fst bns) lthy9';
   519   val (bns_rsp_pre, lthy9) = fold_map (
   506   val (bns_rsp_pre, lthy9) = fold_map (
   520     fn (bn_t, _) => prove_const_rsp qtys Binding.empty [bn_t] (fn _ =>
   507     fn (bn_t, _) => prove_const_rsp qtys Binding.empty [bn_t] (fn _ =>
   521        resolve_tac bns_rsp_pre' 1)) bns lthy8;
   508        resolve_tac bns_rsp_pre' 1)) bns lthy9';
   522   val bns_rsp = flat (map snd bns_rsp_pre);
   509   val bns_rsp = flat (map snd bns_rsp_pre);
   523 
   510 
   524   fun fv_rsp_tac _ = fvbv_rsp_tac alpha_induct raw_fv_defs lthy8 1;
   511   fun fv_rsp_tac _ = fvbv_rsp_tac alpha_induct raw_fv_defs lthy9' 1;
   525 
   512 
   526   val fv_alpha_all = combine_fv_alpha_bns (raw_fvs, raw_fv_bns) (alpha_trms, alpha_bn_trms) bn_nos
   513   val fv_alpha_all = combine_fv_alpha_bns (raw_fvs, raw_fv_bns) (alpha_trms, alpha_bn_trms) bn_nos
   527 
   514 
   528   val fv_rsps = prove_fv_rsp fv_alpha_all alpha_trms fv_rsp_tac lthy9;
   515   val fv_rsps = prove_fv_rsp fv_alpha_all alpha_trms fv_rsp_tac lthy9;
   529   val (fv_rsp_pre, lthy10) = fold_map
   516   val (fv_rsp_pre, lthy10) = fold_map
   558   val qalphabn_defs = map #def qalpha_info
   545   val qalphabn_defs = map #def qalpha_info
   559   
   546   
   560   val _ = warning "Lifting permutations";
   547   val _ = warning "Lifting permutations";
   561   val perm_names = map (fn x => "permute_" ^ x) qty_names
   548   val perm_names = map (fn x => "permute_" ^ x) qty_names
   562   val dd = map2 (fn x => fn y => (x, y, NoSyn)) perm_names raw_perm_funs
   549   val dd = map2 (fn x => fn y => (x, y, NoSyn)) perm_names raw_perm_funs
   563   val lthy13 = define_qperms qtys qty_full_names dd raw_perm_laws lthy12c
   550   val lthy13 = define_qperms qtys qty_full_names [] dd raw_perm_laws lthy12c
   564   
   551   
   565   val q_name = space_implode "_" qty_names;
   552   val q_name = space_implode "_" qty_names;
   566   fun suffix_bind s = Binding.qualify true q_name (Binding.name s);
   553   fun suffix_bind s = Binding.qualify true q_name (Binding.name s);
   567   val _ = warning "Lifting induction";
   554   val _ = warning "Lifting induction";
   568   val constr_names = map (Long_Name.base_name o fst o dest_Const) qconstrs;
   555   val constr_names = map (Long_Name.base_name o fst o dest_Const) [];
   569   val q_induct = Rule_Cases.name constr_names (lift_thm lthy13 qtys [] raw_induct_thm);
   556   val q_induct = Rule_Cases.name constr_names (lift_thm lthy13 qtys [] raw_induct_thm);
   570   fun note_suffix s th ctxt =
   557   fun note_suffix s th ctxt =
   571     snd (Local_Theory.note ((suffix_bind s, []), th) ctxt);
   558     snd (Local_Theory.note ((suffix_bind s, []), th) ctxt);
   572   fun note_simp_suffix s th ctxt =
   559   fun note_simp_suffix s th ctxt =
   573     snd (Local_Theory.note ((suffix_bind s, [Attrib.internal (K Simplifier.simp_add)]), th) ctxt);
   560     snd (Local_Theory.note ((suffix_bind s, [Attrib.internal (K Simplifier.simp_add)]), th) ctxt);
   595   val lthy19 = note_simp_suffix "distinct" q_dis lthy18;
   582   val lthy19 = note_simp_suffix "distinct" q_dis lthy18;
   596   val q_eqvt = map (lift_thm lthy19 qtys []) (raw_bn_eqvt @ raw_fv_eqvt);
   583   val q_eqvt = map (lift_thm lthy19 qtys []) (raw_bn_eqvt @ raw_fv_eqvt);
   597   val (_, lthy20) = Local_Theory.note ((Binding.empty,
   584   val (_, lthy20) = Local_Theory.note ((Binding.empty,
   598     [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19;
   585     [Attrib.internal (fn _ => Nominal_ThmDecls.eqvt_add)]), q_eqvt) lthy19;
   599   val _ = warning "Supports";
   586   val _ = warning "Supports";
   600   val supports = map (prove_supports lthy20 q_perm) qconstrs;
   587   val supports = map (prove_supports lthy20 q_perm) [];
   601   val fin_supp = HOLogic.conj_elims (prove_fs lthy20 q_induct supports qtys);
   588   val fin_supp = HOLogic.conj_elims (prove_fs lthy20 q_induct supports qtys);
   602   val thy3 = Local_Theory.exit_global lthy20;
   589   val thy3 = Local_Theory.exit_global lthy20;
   603   val _ = warning "Instantiating FS";
   590   val _ = warning "Instantiating FS";
   604   val lthy21 = Class.instantiation (qty_full_names, [], @{sort fs}) thy3;
   591   val lthy21 = Class.instantiation (qty_full_names, [], @{sort fs}) thy3;
   605   fun tac _ = Class.intro_classes_tac [] THEN (ALLGOALS (resolve_tac fin_supp))
   592   fun tac _ = Class.intro_classes_tac [] THEN (ALLGOALS (resolve_tac fin_supp))
   617 *}
   604 *}
   618 
   605 
   619 section {* Preparing and parsing of the specification *}
   606 section {* Preparing and parsing of the specification *}
   620 
   607 
   621 ML {* 
   608 ML {* 
   622 (* parsing the datatypes and declaring *)
   609 (* generates the parsed datatypes and 
   623 (* constructors in the local theory    *)
   610    declares the constructors 
   624 fun prepare_dts dt_strs lthy = 
   611 *)
   625 let
   612 fun prepare_dts dt_strs thy = 
   626   val thy = ProofContext.theory_of lthy
   613 let
   627   
   614   fun inter_fs_sort thy (a, S) = 
   628   fun mk_type full_tname tvrs =
   615     (a, Type.inter_sort (Sign.tsig_of thy) (@{sort fs}, S)) 
   629     Type (full_tname, map (fn a => TFree (a, @{sort "{pt, fs}"})) tvrs)
   616 
   630 
   617   fun mk_type tname sorts (cname, cargs, mx) =
   631   fun prep_cnstr full_tname tvs (cname, anno_tys, mx, _) =
       
   632   let
       
   633     val tys = map (Syntax.read_typ lthy o snd) anno_tys
       
   634     val ty = mk_type full_tname tvs
       
   635   in
       
   636     ((cname, tys ---> ty, mx), (cname, tys, mx))
       
   637   end
       
   638   
       
   639   fun prep_dt (tvs, tname, mx, cnstrs) = 
       
   640   let
   618   let
   641     val full_tname = Sign.full_name thy tname
   619     val full_tname = Sign.full_name thy tname
   642     val (cnstrs', cnstrs'') = 
   620     val ty = Type (full_tname, map (TFree o inter_fs_sort thy) sorts)
   643       split_list (map (prep_cnstr full_tname tvs) cnstrs)
       
   644   in
   621   in
   645     (cnstrs', (tvs, tname, mx, cnstrs''))
   622     (cname, cargs ---> ty, mx)
   646   end 
   623   end
   647 
   624 
   648   val (cnstrs, dts) = split_list (map prep_dt dt_strs)
   625   fun prep_constr (cname, cargs, mx, _) (constrs, sorts) =
   649 
   626   let 
   650   val _ = tracing ("Contructors:\n" ^ cat_lines (map @{make_string} cnstrs))
   627     val (cargs', sorts') = 
   651 in
   628       fold_map (Datatype.read_typ thy) (map snd cargs) sorts
   652   lthy
   629       |>> map (map_type_tfree (TFree o inter_fs_sort thy)) 
   653   |> Local_Theory.theory (Sign.add_consts_i (flat cnstrs))
   630   in 
       
   631     (constrs @ [(cname, cargs', mx)], sorts') 
       
   632   end
       
   633   
       
   634   fun prep_dts (tvs, tname, mx, constrs) (constr_trms, dts, sorts) =
       
   635   let 
       
   636     val (constrs', sorts') = 
       
   637       fold prep_constr constrs ([], sorts)
       
   638 
       
   639     val constr_trms' = 
       
   640       map (mk_type tname (rev sorts')) constrs'
       
   641   in 
       
   642     (constr_trms @ constr_trms', dts @ [(tvs, tname, mx, constrs')], sorts') 
       
   643   end
       
   644 
       
   645   val (constr_trms, dts, sorts) = fold prep_dts dt_strs ([], [], []);
       
   646 in
       
   647   thy
       
   648   |> Sign.add_consts_i constr_trms
   654   |> pair dts
   649   |> pair dts
   655 end
   650 end
   656 *}
   651 *}
   657 
   652 
   658 ML {*
   653 ML {*
   659 (* parsing the binding function specification and *)
   654 (* parsing the binding function specification and *)
   660 (* declaring the functions in the local theory    *)
   655 (* declaring the functions in the local theory    *)
   661 fun prepare_bn_funs bn_fun_strs bn_eq_strs lthy =
   656 fun prepare_bn_funs bn_fun_strs bn_eq_strs thy =
   662 let
   657 let
   663   val ((bn_funs, bn_eqs), _) = 
   658   val lthy = Named_Target.theory_init thy
       
   659 
       
   660   val ((bn_funs, bn_eqs), lthy') = 
   664     Specification.read_spec bn_fun_strs bn_eq_strs lthy
   661     Specification.read_spec bn_fun_strs bn_eq_strs lthy
   665 
   662 
   666   fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) 
   663   fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) 
   667   
   664   
   668   val bn_funs' = map prep_bn_fun bn_funs
   665   val bn_funs' = map prep_bn_fun bn_funs
   669 in
   666 in
   670   lthy
   667   (Local_Theory.exit_global lthy')
   671   |> Local_Theory.theory (Sign.add_consts_i bn_funs')
   668   |> Sign.add_consts_i bn_funs'
   672   |> pair (bn_funs', bn_eqs) 
   669   |> pair (bn_funs', bn_eqs) 
   673 end 
   670 end 
   674 *}
   671 *}
   675 
   672 
   676 text {* associates every SOME with the index in the list; drops NONEs *}
   673 text {* associates every SOME with the index in the list; drops NONEs *}
   689     SOME x => x
   686     SOME x => x
   690   | NONE => error ("Cannot find " ^ x ^ " as argument annotation.");
   687   | NONE => error ("Cannot find " ^ x ^ " as argument annotation.");
   691 *}
   688 *}
   692 
   689 
   693 ML {*
   690 ML {*
   694 fun prepare_bclauses dt_strs lthy = 
   691 fun prepare_bclauses dt_strs thy = 
   695 let
   692 let
   696   val annos_bclauses =
   693   val annos_bclauses =
   697     get_cnstrs dt_strs
   694     get_cnstrs dt_strs
   698     |> map (map (fn (_, antys, _, bns) => (map fst antys, bns)))
   695     |> map (map (fn (_, antys, _, bns) => (map fst antys, bns)))
   699 
   696 
   700   fun prep_binder env bn_str =
   697   fun prep_binder env bn_str =
   701     case (Syntax.read_term lthy bn_str) of
   698     case (Syntax.read_term_global thy bn_str) of
   702       Free (x, _) => (NONE, index_lookup env x)
   699       Free (x, _) => (NONE, index_lookup env x)
   703     | Const (a, T) $ Free (x, _) => (SOME (Const (a, T)), index_lookup env x)
   700     | Const (a, T) $ Free (x, _) => (SOME (Const (a, T)), index_lookup env x)
   704     | _ => error ("The term " ^ bn_str ^ " is not allowed as binding function.")
   701     | _ => error ("The term " ^ bn_str ^ " is not allowed as binding function.")
   705  
   702  
   706   fun prep_body env bn_str = index_lookup env bn_str
   703   fun prep_body env bn_str = index_lookup env bn_str
   718     val env = indexify annos (* for every label, associate the index *)
   715     val env = indexify annos (* for every label, associate the index *)
   719   in
   716   in
   720     map (prep_bclause env) bclause_strs
   717     map (prep_bclause env) bclause_strs
   721   end
   718   end
   722 in
   719 in
   723   map (map prep_bclauses) annos_bclauses
   720   (map (map prep_bclauses) annos_bclauses, thy)
   724 end
   721 end
   725 *}
   722 *}
   726 
   723 
   727 text {* 
   724 text {* 
   728   adds an empty binding clause for every argument
   725   adds an empty binding clause for every argument
   730 *}
   727 *}
   731 
   728 
   732 ML {*
   729 ML {*
   733 fun included i bcs = 
   730 fun included i bcs = 
   734 let
   731 let
   735   fun incl (BC (_, bns, bds)) = (member (op =) (map snd bns) i) orelse (member (op =) bds i)
   732   fun incl (BC (_, bns, bds)) = 
       
   733     member (op =) (map snd bns) i orelse member (op =) bds i
   736 in
   734 in
   737   exists incl bcs 
   735   exists incl bcs 
   738 end
   736 end
   739 *}
   737 *}
   740 
   738 
   755   map2 (map2 complt) args bclauses
   753   map2 (map2 complt) args bclauses
   756 end
   754 end
   757 *}
   755 *}
   758 
   756 
   759 ML {*
   757 ML {*
   760 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy = 
   758 fun nominal_datatype2_cmd (opt_thm_name, dt_strs, bn_fun_strs, bn_eq_strs) lthy = 
   761 let
   759 let
   762   fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx)
   760   val (pre_typ_names, pre_typs) = split_list
   763   val lthy0 = 
   761     (map (fn (tvs, tname, mx, _) =>
   764     Local_Theory.theory (Sign.add_types (map prep_typ dt_strs)) lthy
   762       (Binding.name_of tname, (tname, length tvs, mx))) dt_strs)
   765   val (dts, lthy1) = prepare_dts dt_strs lthy0
   763 
   766   val ((bn_funs, bn_eqs), lthy2) = prepare_bn_funs bn_fun_strs bn_eq_strs lthy1
   764   (* this theory is used just for parsing *)
   767   val bclauses = prepare_bclauses dt_strs lthy2
   765   val thy = ProofContext.theory_of lthy  
   768   val bclauses' = complete dt_strs bclauses 
   766   val tmp_thy = Theory.copy thy 
   769 in
   767 
   770   timeit (fn () => nominal_datatype2 dts bn_funs bn_eqs bclauses' lthy |> snd)
   768   val (((dts, (bn_funs, bn_eqs)), bclauses), tmp_thy') = 
       
   769     tmp_thy
       
   770     |> Sign.add_types pre_typs
       
   771     |> prepare_dts dt_strs 
       
   772     ||>> prepare_bn_funs bn_fun_strs bn_eq_strs 
       
   773     ||>> prepare_bclauses dt_strs 
       
   774 
       
   775   val bclauses' = complete dt_strs bclauses
       
   776   val thm_name = 
       
   777     the_default (Binding.name (space_implode "_" pre_typ_names)) opt_thm_name 
       
   778 in
       
   779   timeit (fn () => nominal_datatype2 thm_name dts bn_funs bn_eqs bclauses' lthy |> snd)
   771 end
   780 end
   772 *}
   781 *}
   773 
   782 
   774 ML {* 
   783 ML {* 
   775 (* nominal datatype parser *)
   784 (* nominal datatype parser *)
   776 local
   785 local
   777   structure P = Parse;
   786   structure P = Parse;
   778   structure S = Scan
   787   structure S = Scan
   779 
   788 
   780   fun triple1 ((x, y), z) = (x, y, z)
   789   fun triple ((x, y), z) = (x, y, z)
   781   fun triple2 (x, (y, z)) = (x, y, z)
   790   fun tuple1 ((x, y, z), u) = (x, y, z, u)
   782   fun tuple ((x, y, z), u) = (x, y, z, u)
   791   fun tuple2 (((x, y), z), u) = (x, y, u, z)
   783   fun tswap (((x, y), z), u) = (x, y, u, z)
   792   fun tuple3 ((x, y), (z, u)) = (x, y, z, u)
   784 in
   793 in
   785 
   794 
   786 val _ = Keyword.keyword "bind"
   795 val _ = Keyword.keyword "bind"
   787 val _ = Keyword.keyword "set"
   796 
   788 val _ = Keyword.keyword "res"
   797 val opt_name = Scan.option (P.binding --| Args.colon)
   789 val _ = Keyword.keyword "list"
       
   790 
   798 
   791 val anno_typ = S.option (P.name --| P.$$$ "::") -- P.typ
   799 val anno_typ = S.option (P.name --| P.$$$ "::") -- P.typ
   792 
   800 
   793 val bind_mode = P.$$$ "bind" |--
   801 val bind_mode = P.$$$ "bind" |--
   794   S.optional (Args.parens 
   802   S.optional (Args.parens 
   795     (P.$$$ "list" >> K Lst || P.$$$ "set" >> K Set || P.$$$ "res" >> K Res)) Lst
   803     (Args.$$$ "list" >> K Lst || Args.$$$ "set" >> K Set || Args.$$$ "res" >> K Res)) Lst
   796 
   804 
   797 val bind_clauses = 
   805 val bind_clauses = 
   798   P.enum "," (bind_mode -- S.repeat1 P.term -- (P.$$$ "in" |-- S.repeat1 P.name) >> triple1)
   806   P.enum "," (bind_mode -- S.repeat1 P.term -- (P.$$$ "in" |-- S.repeat1 P.name) >> triple)
   799 
   807 
   800 val cnstr_parser =
   808 val cnstr_parser =
   801   P.binding -- S.repeat anno_typ -- bind_clauses -- P.opt_mixfix >> tswap
   809   P.binding -- S.repeat anno_typ -- bind_clauses -- P.opt_mixfix >> tuple2
   802 
   810 
   803 (* datatype parser *)
   811 (* datatype parser *)
   804 val dt_parser =
   812 val dt_parser =
   805   (P.type_args -- P.binding -- P.opt_mixfix >> triple1) -- 
   813   (P.type_args -- P.binding -- P.opt_mixfix >> triple) -- 
   806     (P.$$$ "=" |-- P.enum1 "|" cnstr_parser) >> tuple
   814     (P.$$$ "=" |-- P.enum1 "|" cnstr_parser) >> tuple1
   807 
   815 
   808 (* binding function parser *)
   816 (* binding function parser *)
   809 val bnfun_parser = 
   817 val bnfun_parser = 
   810   S.optional (P.$$$ "binder" |-- P.fixes -- Parse_Spec.where_alt_specs) ([], [])
   818   S.optional (P.$$$ "binder" |-- P.fixes -- Parse_Spec.where_alt_specs) ([], [])
   811 
   819 
   812 (* main parser *)
   820 (* main parser *)
   813 val main_parser =
   821 val main_parser =
   814   P.and_list1 dt_parser -- bnfun_parser >> triple2
   822   opt_name -- P.and_list1 dt_parser -- bnfun_parser >> tuple3
   815 
   823 
   816 end
   824 end
   817 
   825 
   818 (* Command Keyword *)
   826 (* Command Keyword *)
   819 
       
   820 val _ = Outer_Syntax.local_theory "nominal_datatype" "test" Keyword.thy_decl
   827 val _ = Outer_Syntax.local_theory "nominal_datatype" "test" Keyword.thy_decl
   821   (main_parser >> nominal_datatype2_cmd)
   828   (main_parser >> nominal_datatype2_cmd)
   822 *}
   829 *}
   823 
   830 
   824 
   831