Nominal/Parser.thy
changeset 1284 212f3ab40cc2
parent 1283 6a133abb7633
child 1285 e3ac56d3b7af
equal deleted inserted replaced
1283:6a133abb7633 1284:212f3ab40cc2
   135   lthy
   135   lthy
   136   |> Local_Theory.theory_result (Datatype.add_datatype conf dt_names' dts')
   136   |> Local_Theory.theory_result (Datatype.add_datatype conf dt_names' dts')
   137 end 
   137 end 
   138 *}
   138 *}
   139 
   139 
   140 ML {* Primrec.add_primrec *}
       
   141 
       
   142 ML {*
   140 ML {*
   143 fun raw_bn_fun_decl dt_names dts bn_funs bn_eqs lthy =
   141 fun raw_bn_fun_decl dt_names dts bn_funs bn_eqs lthy =
   144 let
   142 let
   145   val thy = ProofContext.theory_of lthy
   143   val thy = ProofContext.theory_of lthy
   146 
   144 
   159   val bn_fun_env = bn_fun_strs ~~ bn_fun_strs'
   157   val bn_fun_env = bn_fun_strs ~~ bn_fun_strs'
   160   
   158   
   161   val bn_funs' = map (fn (bn, ty, mx) => 
   159   val bn_funs' = map (fn (bn, ty, mx) => 
   162     (raw_bind bn, SOME (replace_typ dt_env ty), mx)) bn_funs
   160     (raw_bind bn, SOME (replace_typ dt_env ty), mx)) bn_funs
   163   
   161   
   164   val bn_eqs' = map (fn trm => 
   162   val bn_eqs' = map (fn (_, trm) => 
   165     (Attrib.empty_binding, replace_term (ctrs_env @ bn_fun_env) dt_env trm)) bn_eqs
   163     (Attrib.empty_binding, replace_term (ctrs_env @ bn_fun_env) dt_env trm)) bn_eqs
   166 in
   164 in
   167   if null bn_eqs 
   165   if null bn_eqs 
   168   then (([], []), lthy)
   166   then (([], []), lthy)
   169   else Primrec.add_primrec bn_funs' bn_eqs' lthy 
   167   else Primrec.add_primrec bn_funs' bn_eqs' lthy 
   170 end 
   168 end 
   171 *}
   169 *}
   172 
   170 
   173 ML {* 
   171 ML {* 
   174 fun nominal_datatype2 dts bn_funs bn_eqs lthy =
   172 fun nominal_datatype2 dts bn_funs bn_eqs binds lthy =
   175 let
   173 let
   176   val dts_names = map (fn (_, s, _, _) => Binding.name_of s) dts
   174   val dts_names = map (fn (_, s, _, _) => Binding.name_of s) dts
   177 in
   175 in
   178   lthy
   176   lthy
   179   |> raw_dts_decl dts_names dts
   177   |> raw_dts_decl dts_names dts
   180   ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs
   178   ||>> raw_bn_fun_decl dts_names dts bn_funs bn_eqs
   181 end
   179 end
   182 *}
   180 *}
   183 
   181 
   184 ML {*
   182 
   185 fun get_constrs2 lthy dts =
   183 ML {* 
       
   184 (* parsing the datatypes and declaring *)
       
   185 (* constructors in the local theory    *)
       
   186 fun prepare_dts dt_strs lthy = 
   186 let
   187 let
   187   val thy = ProofContext.theory_of lthy
   188   val thy = ProofContext.theory_of lthy
   188 
   189   
   189   (* makes a full named type out of a binding with tvars applied to it *)
   190   fun mk_type full_tname tvrs =
   190   fun mk_type thy bind tvrs =
   191     Type (full_tname, map (fn a => TVar ((a, 0), [])) tvrs)
   191     Type (Sign.full_name thy bind, map (fn s => TVar ((s, 0), [])) tvrs)
   192 
   192 
   193   fun prep_cnstr lthy full_tname tvs (cname, anno_tys, mx, _) =
   193   val dts' = map (fn (tvrs, tname, _, constrs) => (mk_type thy tname tvrs, constrs)) dts
   194   let
   194 in
   195     val tys = map (Syntax.read_typ lthy o snd) anno_tys
   195   flat (map (fn (ty, constrs) => map (fn (bn, tys, mx) =>  (bn, tys ---> ty, mx)) constrs) dts')
   196     val ty = mk_type full_tname tvs
   196 end
   197   in
   197 *}
   198     ((cname, tys ---> ty, mx), (cname, tys, mx))
   198 
   199   end
   199 ML {* 
   200   
   200 fun find_all _ [] _ = []
   201   fun prep_dt lthy (tvs, tname, mx, cnstrs) = 
   201   | find_all eq ((y, z)::xs) x = 
   202   let
   202       if eq (x, y) 
   203     val full_tname = Sign.full_name thy tname
   203       then z::find_all eq xs x 
   204     val (cnstrs', cnstrs'') = 
   204       else find_all eq xs x 
   205       split_list (map (prep_cnstr lthy full_tname tvs) cnstrs)
   205 *}
   206   in
   206 
   207     (cnstrs', (tvs, tname, mx, cnstrs''))
   207 ML {*
   208   end 
       
   209 
       
   210   val (cnstrs, dts) = 
       
   211     split_list (map (prep_dt lthy) dt_strs)
       
   212 in
       
   213   lthy
       
   214   |> Local_Theory.theory (Sign.add_consts_i (flat cnstrs))
       
   215   |> pair dts
       
   216 end
       
   217 *}
       
   218 
       
   219 ML {*
       
   220 (* parsing the function specification and *)
       
   221 (* declaring the functions in the local theory *)
       
   222 fun prepare_bn_funs bn_fun_strs bn_eq_strs lthy =
       
   223 let
       
   224   fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) 
       
   225 
       
   226   val ((bn_funs, bn_eqs), _) = 
       
   227     Specification.read_spec bn_fun_strs bn_eq_strs lthy
       
   228 
       
   229   val bn_funs' = map prep_bn_fun bn_funs
       
   230 in
       
   231   lthy
       
   232   |> Local_Theory.theory (Sign.add_consts_i bn_funs')
       
   233   |> pair (bn_funs', bn_eqs) 
       
   234 end 
       
   235 *}
       
   236 
       
   237 ML {*
       
   238 fun forth (_, _, _, x) = x
       
   239 
       
   240 fun find_all eq [] _ = []
       
   241   | find_all eq ((key, value)::xs) key' = 
       
   242       let
       
   243         val values = find_all eq xs key'
       
   244       in if eq (key', key) then value :: values else values end;
       
   245 
   208 fun mk_env xs =
   246 fun mk_env xs =
   209   let
   247   let
   210     fun mapp (_: int) [] = []
   248     fun mapp (_: int) [] = []
   211       | mapp i ((a, _) :: xs) = 
   249       | mapp i ((a, _) :: xs) = 
   212          case a of
   250          case a of
   219     SOME x => x
   257     SOME x => x
   220   | NONE => error ("cannot find " ^ x ^ " in the binding specification.")  
   258   | NONE => error ("cannot find " ^ x ^ " in the binding specification.")  
   221 *}
   259 *}
   222 
   260 
   223 ML {*
   261 ML {*
   224 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy =
   262 fun prepare_binds dt_strs lthy = 
   225 let
   263 let
   226   fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx);
   264   fun prep_bn env str =
   227 
   265         (case Syntax.read_term lthy str of
   228   (* adding the types for parsing datatypes *)
       
   229   val lthy_tmp1 = lthy
       
   230     |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs))
       
   231 
       
   232   (* parsing the datatypes *)
       
   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)
       
   237   
       
   238       fun prep_dt lthy (tvs, tname, mx, cnstrs) = 
       
   239         (tvs, tname, mx, map (prep_cnstr lthy) cnstrs)
       
   240     in
       
   241       map (prep_dt lthy_tmp1) dt_strs
       
   242     end
       
   243  
       
   244   (* adding constructors for parsing functions *)
       
   245   val lthy_tmp2 = lthy_tmp1
       
   246     |> Local_Theory.theory (Sign.add_consts_i (get_constrs2 lthy dts_prep))
       
   247 
       
   248   (* parsing the function specification *)
       
   249   val (bn_fun_prep, bn_eq_prep) =
       
   250     let 
       
   251       val ((bn_fun_aux, bn_eq_aux), _) = Specification.read_spec bn_fun_strs bn_eq_strs lthy_tmp2
       
   252 
       
   253       fun prep_bn_fun ((bn, T), mx) = (bn, T, mx) 
       
   254       fun prep_bn_eq (attr, t) = t
       
   255     in
       
   256       (map prep_bn_fun bn_fun_aux, map prep_bn_eq bn_eq_aux)
       
   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)
   266            Free (x, _) => (env_lookup env x, NONE)
   269          | Const (a, T) $ Free (x, _) => (env_lookup env x, SOME (Const (a, T)))
   267          | Const (a, T) $ Free (x, _) => (env_lookup env x, SOME (Const (a, T)))
   270          | _ => error (str ^ " not allowed as binding specification."))   
   268          | x => error (str ^ " not allowed as binding specification."))   
   271  
   269  
   272       fun prep_typ env (opt_name, _) = 
   270   fun prep_typ env (opt_name, _) = 
   273         (case opt_name of
   271         (case opt_name of
   274            NONE => []
   272            NONE => []
   275          | SOME x => find_all (op=) env x)
   273          | SOME x => find_all (op=) env x)
   276         
   274         
   277       fun prep_binds (_, anno_tys, _, bind_strs) = 
   275   fun prep_binds (_, anno_tys, _, bind_strs) = 
   278       let
   276   let
   279         val env = mk_env anno_tys
   277     val env = mk_env anno_tys
   280         val binds = map (fn (x, y) => (x, prep_bn env y)) bind_strs  
   278     val binds = map (fn (x, y) => (x, prep_bn env y)) bind_strs  
   281       in
   279   in
   282         map (prep_typ binds) anno_tys
   280     map (prep_typ binds) anno_tys
   283       end
   281   end
   284     in
   282 in
   285       map ((map prep_binds) o #4) dt_strs
   283   map ((map prep_binds) o forth) dt_strs
   286     end
   284 end
   287 
   285 *}
   288     val _ = tracing (PolyML.makestring binds)
   286 
   289 in
   287 ML {*
   290   nominal_datatype2 dts_prep bn_fun_prep bn_eq_prep lthy |> snd 
   288 fun nominal_datatype2_cmd (dt_strs, bn_fun_strs, bn_eq_strs) lthy =
   291 end
   289 let
   292 *}
   290   val t = start_timing ()
       
   291 
       
   292   fun prep_typ (tvs, tname, mx, _) = (tname, length tvs, mx)
       
   293 
       
   294   val ((dts, (bn_fun, bn_eq)), binds) = 
       
   295     lthy 
       
   296     |> Local_Theory.theory (Sign.add_types (map prep_typ dt_strs))
       
   297     |> prepare_dts dt_strs
       
   298     ||>> prepare_bn_funs bn_fun_strs bn_eq_strs
       
   299     ||> prepare_binds dt_strs
       
   300   
       
   301   val _ = tracing (PolyML.makestring binds)
       
   302   val _ = tracing (#message (end_timing t))
       
   303 in
       
   304   nominal_datatype2 dts bn_fun bn_eq binds lthy |> snd
       
   305 end
       
   306 *}
       
   307 
   293 
   308 
   294 (* Command Keyword *)
   309 (* Command Keyword *)
   295 
       
   296 
   310 
   297 ML {*
   311 ML {*
   298 let
   312 let
   299    val kind = OuterKeyword.thy_decl
   313    val kind = OuterKeyword.thy_decl
   300 in
   314 in