src/HOLCF/Tools/domain/domain_extender.ML
changeset 30916 a3d2128cac92
parent 30915 f8877f60e1ee
child 30919 dcf8a7a66bd1
equal deleted inserted replaced
30915:f8877f60e1ee 30916:a3d2128cac92
     4 Theory extender for domain command, including theory syntax.
     4 Theory extender for domain command, including theory syntax.
     5 *)
     5 *)
     6 
     6 
     7 signature DOMAIN_EXTENDER =
     7 signature DOMAIN_EXTENDER =
     8 sig
     8 sig
     9   val add_domain: string * ((bstring * string list) *
     9   val add_domain: string * ((bstring * string list * mixfix) *
    10     (string * mixfix * (bool * string option * string) list) list) list
    10     (string * mixfix * (bool * string option * string) list) list) list
    11     -> theory -> theory
    11     -> theory -> theory
    12   val add_domain_i: string * ((bstring * string list) *
    12   val add_domain_i: string * ((bstring * string list * mixfix) *
    13     (string * mixfix * (bool * string option * typ) list) list) list
    13     (string * mixfix * (bool * string option * typ) list) list) list
    14     -> theory -> theory
    14     -> theory -> theory
    15 end;
    15 end;
    16 
    16 
    17 structure Domain_Extender: DOMAIN_EXTENDER =
    17 structure Domain_Extender: DOMAIN_EXTENDER =
    78 
    78 
    79 (* ----- calls for building new thy and thms -------------------------------- *)
    79 (* ----- calls for building new thy and thms -------------------------------- *)
    80 
    80 
    81 fun gen_add_domain prep_typ (comp_dnam, eqs''') thy''' =
    81 fun gen_add_domain prep_typ (comp_dnam, eqs''') thy''' =
    82   let
    82   let
    83     val dtnvs = map ((fn (dname,vs) => 
    83     val dtnvs = map ((fn (dname,vs,mx) => 
    84 			 (Sign.full_bname thy''' dname, map (Syntax.read_typ_global thy''') vs))
    84 			 (Sign.full_bname thy''' dname, map (Syntax.read_typ_global thy''') vs, mx))
    85                    o fst) eqs''';
    85                    o fst) eqs''';
    86     val cons''' = map snd eqs''';
    86     val cons''' = map snd eqs''';
    87     fun thy_type  (dname,tvars)  = (Binding.name (Long_Name.base_name dname), length tvars, NoSyn);
    87     fun thy_type  (dname,tvars,mx) = (Binding.name (Long_Name.base_name dname), length tvars, mx);
    88     fun thy_arity (dname,tvars)  = (dname, map (snd o dest_TFree) tvars, pcpoS);
    88     fun thy_arity (dname,tvars,mx) = (dname, map (snd o dest_TFree) tvars, pcpoS);
    89     val thy'' = thy''' |> Sign.add_types     (map thy_type  dtnvs)
    89     val thy'' = thy''' |> Sign.add_types (map thy_type dtnvs)
    90 		       |> fold (AxClass.axiomatize_arity o thy_arity) dtnvs;
    90 		       |> fold (AxClass.axiomatize_arity o thy_arity) dtnvs;
    91     val cons'' = map (map (upd_third (map (upd_third (prep_typ thy''))))) cons''';
    91     val cons'' = map (map (upd_third (map (upd_third (prep_typ thy''))))) cons''';
    92     val eqs' = check_and_sort_domain (dtnvs,cons'') thy'';
    92     val dtnvs' = map (fn (dname,vs,mx) => (dname,vs)) dtnvs;
       
    93     val eqs' = check_and_sort_domain (dtnvs',cons'') thy'';
    93     val thy' = thy'' |> Domain_Syntax.add_syntax (comp_dnam,eqs');
    94     val thy' = thy'' |> Domain_Syntax.add_syntax (comp_dnam,eqs');
    94     val dts  = map (Type o fst) eqs';
    95     val dts  = map (Type o fst) eqs';
    95     val new_dts = map (fn ((s,Ts),_) => (s, map (fst o dest_TFree) Ts)) eqs';
    96     val new_dts = map (fn ((s,Ts),_) => (s, map (fst o dest_TFree) Ts)) eqs';
    96     fun strip ss = Library.drop (find_index_eq "'" ss +1, ss);
    97     fun strip ss = Library.drop (find_index_eq "'" ss +1, ss);
    97     fun typid (Type  (id,_)) =
    98     fun typid (Type  (id,_)) =
   127 
   128 
   128 local structure P = OuterParse and K = OuterKeyword in
   129 local structure P = OuterParse and K = OuterKeyword in
   129 
   130 
   130 val _ = OuterKeyword.keyword "lazy";
   131 val _ = OuterKeyword.keyword "lazy";
   131 
   132 
   132 val dest_decl =
   133 val dest_decl : (bool * string option * string) parser =
   133   P.$$$ "(" |-- Scan.optional (P.$$$ "lazy" >> K true) false --
   134   P.$$$ "(" |-- Scan.optional (P.$$$ "lazy" >> K true) false --
   134     (P.name >> SOME) -- (P.$$$ "::" |-- P.typ)  --| P.$$$ ")" >> P.triple1
   135     (P.name >> SOME) -- (P.$$$ "::" |-- P.typ)  --| P.$$$ ")" >> P.triple1
   135   || P.$$$ "(" |-- P.$$$ "lazy" |-- P.typ --| P.$$$ ")"
   136   || P.$$$ "(" |-- P.$$$ "lazy" |-- P.typ --| P.$$$ ")"
   136        >> (fn t => (true,NONE,t))
   137        >> (fn t => (true,NONE,t))
   137   || P.typ >> (fn t => (false,NONE,t));
   138   || P.typ >> (fn t => (false,NONE,t));
   138 
   139 
   139 val cons_decl =
   140 val cons_decl =
   140   P.name -- Scan.repeat dest_decl -- P.opt_mixfix
   141   P.name -- Scan.repeat dest_decl -- P.opt_mixfix;
   141   >> (fn ((c, ds), mx) => (c, mx, ds));
       
   142 
   142 
   143 val type_var' = (P.type_ident ^^ 
   143 val type_var' =
   144                  Scan.optional (P.$$$ "::" ^^ P.!!! P.sort) "");
   144   (P.type_ident ^^ Scan.optional (P.$$$ "::" ^^ P.!!! P.sort) "");
   145 val type_args' = type_var' >> single ||
       
   146                  P.$$$ "(" |-- P.!!! (P.list1 type_var' --| P.$$$ ")") ||
       
   147  		 Scan.succeed [];
       
   148 
   145 
   149 val domain_decl = (type_args' -- P.name >> Library.swap) -- 
   146 val type_args' =
   150                   (P.$$$ "=" |-- P.enum1 "|" cons_decl);
   147   type_var' >> single ||
       
   148   P.$$$ "(" |-- P.!!! (P.list1 type_var' --| P.$$$ ")") ||
       
   149   Scan.succeed [];
       
   150 
       
   151 val domain_decl =
       
   152   (type_args' -- P.name -- P.opt_infix) --
       
   153   (P.$$$ "=" |-- P.enum1 "|" cons_decl);
       
   154 
   151 val domains_decl =
   155 val domains_decl =
   152   Scan.option (P.$$$ "(" |-- P.name --| P.$$$ ")") -- P.and_list1 domain_decl
   156   Scan.option (P.$$$ "(" |-- P.name --| P.$$$ ")") --
   153   >> (fn (opt_name, doms) =>
   157   P.and_list1 domain_decl;
   154       (case opt_name of NONE => space_implode "_" (map (#1 o #1) doms) | SOME s => s, doms));
   158 
       
   159 fun mk_domain (opt_name : string option, doms : (((string list * bstring) * mixfix) *
       
   160     ((string * (bool * string option * string) list) * mixfix) list) list ) =
       
   161   let
       
   162     val names = map (fn (((_, t), _), _) => t) doms;
       
   163     val specs = map (fn (((vs, t), mx), cons) =>
       
   164       ((t, vs, mx), map (fn ((c, ds), mx) => (c, mx, ds)) cons)) doms;
       
   165     val big_name =
       
   166       case opt_name of NONE => space_implode "_" names | SOME s => s;
       
   167   in add_domain (big_name, specs) end;
   155 
   168 
   156 val _ =
   169 val _ =
   157   OuterSyntax.command "domain" "define recursive domains (HOLCF)" K.thy_decl
   170   OuterSyntax.command "domain" "define recursive domains (HOLCF)" K.thy_decl
   158     (domains_decl >> (Toplevel.theory o add_domain));
   171     (domains_decl >> (Toplevel.theory o mk_domain));
   159 
   172 
   160 end;
   173 end;
   161 
   174 
   162 end;
   175 end;