Nominal/Parser.thy
changeset 1283 6a133abb7633
parent 1266 b0a120469041
child 1284 212f3ab40cc2
equal deleted inserted replaced
1282:ea46a354f382 1283:6a133abb7633
    29           ^^^^^^^^^
    29           ^^^^^^^^^
    30           the equations of the binding functions
    30           the equations of the binding functions
    31           (Trueprop equations)
    31           (Trueprop equations)
    32 *}
    32 *}
    33 
    33 
       
    34 ML {*
       
    35 
       
    36 *}
       
    37 
    34 text {*****************************************************}
    38 text {*****************************************************}
    35 ML {* 
    39 ML {* 
    36 (* nominal datatype parser *)
    40 (* nominal datatype parser *)
    37 local
    41 local
    38   structure P = OuterParse
    42   structure P = OuterParse
    39 
    43 
    40   fun tuple ((x, y, z), u) = (x, y, z, u)
    44   fun tuple ((x, y, z), u) = (x, y, z, u)
       
    45   fun tswap (((x, y), z), u) = (x, y, u, z)
    41 in
    46 in
    42 
    47 
    43 val _ = OuterKeyword.keyword "bind"
    48 val _ = OuterKeyword.keyword "bind"
    44 val anno_typ = Scan.option (P.name --| P.$$$ "::") -- P.typ
    49 val anno_typ = Scan.option (P.name --| P.$$$ "::") -- P.typ
    45 
    50 
    46 (* binding specification *)
    51 (* binding specification *)
    47 (* maybe use and_list *)
    52 (* maybe use and_list *)
    48 val bind_parser = 
    53 val bind_parser = 
    49   P.enum "," ((P.$$$ "bind" |-- P.term) -- (P.$$$ "in" |-- P.name))
    54   P.enum "," ((P.$$$ "bind" |-- P.term) -- (P.$$$ "in" |-- P.name) >> swap)
    50 
    55 
    51 val constr_parser =
    56 val constr_parser =
    52   P.binding -- Scan.repeat anno_typ
    57   P.binding -- Scan.repeat anno_typ
    53 
    58 
    54 (* datatype parser *)
    59 (* datatype parser *)
    55 val dt_parser =
    60 val dt_parser =
    56   (P.type_args -- P.binding -- P.opt_infix >> P.triple1) -- 
    61   (P.type_args -- P.binding -- P.opt_mixfix >> P.triple1) -- 
    57     (P.$$$ "=" |-- P.enum1 "|" (constr_parser -- bind_parser -- P.opt_mixfix >> P.triple_swap)) >> tuple
    62     (P.$$$ "=" |-- P.enum1 "|" (constr_parser -- bind_parser -- P.opt_mixfix >> tswap)) >> tuple
    58 
    63 
    59 (* function equation parser *)
    64 (* function equation parser *)
    60 val fun_parser = 
    65 val fun_parser = 
    61   Scan.optional (P.$$$ "binder" |-- P.fixes -- SpecParse.where_alt_specs) ([],[])
    66   Scan.optional (P.$$$ "binder" |-- P.fixes -- SpecParse.where_alt_specs) ([],[])
    62 
    67 
   129 in
   134 in
   130   lthy
   135   lthy
   131   |> Local_Theory.theory_result (Datatype.add_datatype conf dt_names' dts')
   136   |> Local_Theory.theory_result (Datatype.add_datatype conf dt_names' dts')
   132 end 
   137 end 
   133 *}
   138 *}
       
   139 
       
   140 ML {* Primrec.add_primrec *}
   134 
   141 
   135 ML {*
   142 ML {*
   136 fun raw_bn_fun_decl dt_names dts bn_funs bn_eqs lthy =
   143 fun raw_bn_fun_decl dt_names dts bn_funs bn_eqs lthy =
   137 let
   144 let
   138   val thy = ProofContext.theory_of lthy
   145   val thy = ProofContext.theory_of lthy
   149 
   156 
   150   val bn_fun_strs = get_bn_fun_strs bn_funs
   157   val bn_fun_strs = get_bn_fun_strs bn_funs
   151   val bn_fun_strs' = add_raws bn_fun_strs
   158   val bn_fun_strs' = add_raws bn_fun_strs
   152   val bn_fun_env = bn_fun_strs ~~ bn_fun_strs'
   159   val bn_fun_env = bn_fun_strs ~~ bn_fun_strs'
   153   
   160   
   154   val bn_funs' = map (fn (bn, opt_ty, mx) => 
   161   val bn_funs' = map (fn (bn, ty, mx) => 
   155     (raw_bind bn, Option.map (replace_typ (dt_full_names ~~ dt_full_names')) opt_ty, mx)) bn_funs
   162     (raw_bind bn, SOME (replace_typ dt_env ty), mx)) bn_funs
   156   
   163   
   157   val bn_eqs' = map (fn trm => 
   164   val bn_eqs' = map (fn trm => 
   158     (Attrib.empty_binding, replace_term (ctrs_env @ bn_fun_env) dt_env trm)) bn_eqs
   165     (Attrib.empty_binding, replace_term (ctrs_env @ bn_fun_env) dt_env trm)) bn_eqs
   159 in
   166 in
   160   if null bn_eqs 
   167   if null bn_eqs 
   173   ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs
   180   ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs
   174 end
   181 end
   175 *}
   182 *}
   176 
   183 
   177 ML {*
   184 ML {*
   178 fun get_constrs2 thy dts =
   185 fun get_constrs2 lthy dts =
   179 let
   186 let
       
   187   val thy = ProofContext.theory_of lthy
       
   188 
   180   (* makes a full named type out of a binding with tvars applied to it *)
   189   (* makes a full named type out of a binding with tvars applied to it *)
   181   fun mk_type thy bind tvrs =
   190   fun mk_type thy bind tvrs =
   182     Type (Sign.full_name thy bind, map (fn s => TVar ((s, 0), [])) tvrs)
   191     Type (Sign.full_name thy bind, map (fn s => TVar ((s, 0), [])) tvrs)
   183 
   192 
   184   val dts' = map (fn (tvrs, tname, _, constrs) => (mk_type thy tname tvrs, constrs)) dts
   193   val dts' = map (fn (tvrs, tname, _, constrs) => (mk_type thy tname tvrs, constrs)) dts
   185 in
   194 in
   186   flat (map (fn (ty, constrs) => map (fn (bn, tys, mx) =>  (bn, tys ---> ty, mx)) constrs) dts')
   195   flat (map (fn (ty, constrs) => map (fn (bn, tys, mx) =>  (bn, tys ---> ty, mx)) constrs) dts')
   187 end
   196 end
   188 *}
   197 *}
   189 
   198 
       
   199 ML {* 
       
   200 fun find_all _ [] _ = []
       
   201   | find_all eq ((y, z)::xs) x = 
       
   202       if eq (x, y) 
       
   203       then z::find_all eq xs x 
       
   204       else find_all eq xs x 
       
   205 *}
       
   206 
       
   207 ML {*
       
   208 fun mk_env xs =
       
   209   let
       
   210     fun mapp (_: int) [] = []
       
   211       | mapp i ((a, _) :: xs) = 
       
   212          case a of
       
   213            NONE => mapp (i + 1) xs
       
   214          | SOME x => (x, i) :: mapp (i + 1) xs
       
   215   in mapp 0 xs end
       
   216 
       
   217 fun env_lookup xs x =
       
   218   case AList.lookup (op =) xs x of
       
   219     SOME x => x
       
   220   | NONE => error ("cannot find " ^ x ^ " in the binding specification.")  
       
   221 *}
       
   222 
   190 ML {*
   223 ML {*
   191 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy =
   224 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy =
   192 let
   225 let
   193   val thy = ProofContext.theory_of lthy
       
   194 
       
   195   fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx);
   226   fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx);
   196 
   227 
   197   (* adding the types for parsing datatypes *)
   228   (* adding the types for parsing datatypes *)
   198   val lthy_tmp = lthy
   229   val lthy_tmp1 = lthy
   199     |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs))
   230     |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs))
   200 
   231 
   201   fun prep_cnstr lthy (((cname, atys), mx), binders) =
   232   (* parsing the datatypes *)
   202     (cname, map (Syntax.read_typ lthy o snd) atys, mx)
   233   val dts_prep = 
       
   234     let
       
   235       fun prep_cnstr lthy (cname, anno_tys, mx, _) =
       
   236         (cname, map (Syntax.read_typ lthy o snd) anno_tys, mx)
   203   
   237   
   204   fun prep_dt lthy (tvs, tname, mx, cnstrs) = 
   238       fun prep_dt lthy (tvs, tname, mx, cnstrs) = 
   205     (tvs, tname, mx, map (prep_cnstr lthy) cnstrs)
   239         (tvs, tname, mx, map (prep_cnstr lthy) cnstrs)
   206 
   240     in
   207   (* parsing the datatypes *)
   241       map (prep_dt lthy_tmp1) dt_strs
   208   val dts_prep = map (prep_dt lthy_tmp) dt_strs
   242     end
   209 
   243  
   210   (* adding constructors for parsing functions *)
   244   (* adding constructors for parsing functions *)
   211   val lthy_tmp2 = lthy_tmp
   245   val lthy_tmp2 = lthy_tmp1
   212     |> Local_Theory.theory (Sign.add_consts_i (get_constrs2 thy dts_prep))
   246     |> Local_Theory.theory (Sign.add_consts_i (get_constrs2 lthy dts_prep))
   213 
   247 
   214   val (bn_fun_aux, bn_eq_aux) = fst (Specification.read_spec bn_fun_strs bn_eq_strs lthy_tmp2)
   248   (* parsing the function specification *)
   215 
   249   val (bn_fun_prep, bn_eq_prep) =
   216   fun prep_bn_fun ((bn, T), mx) = (bn, SOME T, mx) 
   250     let 
   217 
   251       val ((bn_fun_aux, bn_eq_aux), _) = Specification.read_spec bn_fun_strs bn_eq_strs lthy_tmp2
   218   fun prep_bn_eq (attr, t) = t
   252 
   219 
   253       fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) 
   220   val bn_fun_prep = map prep_bn_fun bn_fun_aux
   254       fun prep_bn_eq (attr, t) = t
   221   val bn_eq_prep = map prep_bn_eq bn_eq_aux 
   255     in
   222 in
   256       (map prep_bn_fun bn_fun_aux, map prep_bn_eq bn_eq_aux)
   223   nominal_datatype2 dts_prep bn_fun_prep bn_eq_prep lthy |> snd
   257     end 
       
   258 
       
   259   (* adding functions for parsing binders *)
       
   260   val lthy_tmp3 = lthy_tmp2
       
   261     |> Local_Theory.theory (Sign.add_consts_i bn_fun_prep)
       
   262 
       
   263   (* parsing the binding structure *)
       
   264   val binds = 
       
   265     let
       
   266       fun prep_bn env str =
       
   267         (case Syntax.read_term lthy_tmp3 str of
       
   268            Free (x, _) => (env_lookup env x, NONE)
       
   269          | Const (a, T) $ Free (x, _) => (env_lookup env x, SOME (Const (a, T)))
       
   270          | _ => error (str ^ " not allowed as binding specification."))   
       
   271  
       
   272       fun prep_typ env (opt_name, _) = 
       
   273         (case opt_name of
       
   274            NONE => []
       
   275          | SOME x => find_all (op=) env x)
       
   276         
       
   277       fun prep_binds (_, anno_tys, _, bind_strs) = 
       
   278       let
       
   279         val env = mk_env anno_tys
       
   280         val binds = map (fn (x, y) => (x, prep_bn env y)) bind_strs  
       
   281       in
       
   282         map (prep_typ binds) anno_tys
       
   283       end
       
   284     in
       
   285       map ((map prep_binds) o #4) dt_strs
       
   286     end
       
   287 
       
   288     val _ = tracing (PolyML.makestring binds)
       
   289 in
       
   290   nominal_datatype2 dts_prep bn_fun_prep bn_eq_prep lthy |> snd 
   224 end
   291 end
   225 *}
   292 *}
   226 
   293 
   227 (* Command Keyword *)
   294 (* Command Keyword *)
       
   295 
       
   296 
   228 ML {*
   297 ML {*
   229 let
   298 let
   230    val kind = OuterKeyword.thy_decl
   299    val kind = OuterKeyword.thy_decl
   231 in
   300 in
   232    OuterSyntax.local_theory "nominal_datatype" "test" kind 
   301    OuterSyntax.local_theory "nominal_datatype" "test" kind