src/Pure/type.ML
author wenzelm
Tue Aug 14 23:22:58 2007 +0200 (2007-08-14 ago)
changeset 24274 cb9236269af1
parent 23655 d2d1138e0ddc
child 24484 013b98b57b86
permissions -rw-r--r--
type mode: models certification mode (default, syntax, abbrev);
replaced certify_typ_syntax/abbrev by certify_typ_mode;
     1 (*  Title:      Pure/type.ML
     2     ID:         $Id$
     3     Author:     Tobias Nipkow, Lawrence C Paulson, and Markus Wenzel
     4 
     5 Type signatures and certified types, special treatment of type vars,
     6 matching and unification of types, extend and merge type signatures.
     7 *)
     8 
     9 signature TYPE =
    10 sig
    11   (*type signatures and certified types*)
    12   datatype decl =
    13     LogicalType of int |
    14     Abbreviation of string list * typ * bool |
    15     Nonterminal
    16   type tsig
    17   val rep_tsig: tsig ->
    18    {classes: NameSpace.T * Sorts.algebra,
    19     default: sort,
    20     types: (decl * serial) NameSpace.table,
    21     log_types: string list,
    22     witness: (typ * sort) option}
    23   val empty_tsig: tsig
    24   val defaultS: tsig -> sort
    25   val logical_types: tsig -> string list
    26   val universal_witness: tsig -> (typ * sort) option
    27   val eq_sort: tsig -> sort * sort -> bool
    28   val subsort: tsig -> sort * sort -> bool
    29   val of_sort: tsig -> typ * sort -> bool
    30   val inter_sort: tsig -> sort * sort -> sort
    31   val cert_class: tsig -> class -> class
    32   val cert_sort: tsig -> sort -> sort
    33   val witness_sorts: tsig -> sort list -> sort list -> (typ * sort) list
    34   type mode
    35   val mode_default: mode
    36   val mode_syntax: mode
    37   val mode_abbrev: mode
    38   val cert_typ_mode: mode -> tsig -> typ -> typ
    39   val cert_typ: tsig -> typ -> typ
    40   val arity_number: tsig -> string -> int
    41   val arity_sorts: Pretty.pp -> tsig -> string -> sort -> sort list
    42 
    43   (*special treatment of type vars*)
    44   val strip_sorts: typ -> typ
    45   val no_tvars: typ -> typ
    46   val varify: (string * sort) list -> term -> ((string * sort) * indexname) list * term
    47   val freeze_thaw_type: typ -> typ * (typ -> typ)
    48   val freeze_type: typ -> typ
    49   val freeze_thaw: term -> term * (term -> term)
    50   val freeze: term -> term
    51 
    52   (*matching and unification*)
    53   exception TYPE_MATCH
    54   type tyenv
    55   val lookup: tyenv * (indexname * sort) -> typ option
    56   val typ_match: tsig -> typ * typ -> tyenv -> tyenv
    57   val typ_instance: tsig -> typ * typ -> bool
    58   val raw_match: typ * typ -> tyenv -> tyenv
    59   val raw_matches: typ list * typ list -> tyenv -> tyenv
    60   val raw_instance: typ * typ -> bool
    61   exception TUNIFY
    62   val unify: tsig -> typ * typ -> tyenv * int -> tyenv * int
    63   val raw_unify: typ * typ -> tyenv -> tyenv
    64   val raw_unifys: typ list * typ list -> tyenv -> tyenv
    65   val could_unify: typ * typ -> bool
    66   val could_unifys: typ list * typ list -> bool
    67   val eq_type: tyenv -> typ * typ -> bool
    68 
    69   (*extend and merge type signatures*)
    70   val add_class: Pretty.pp -> NameSpace.naming -> bstring * class list -> tsig -> tsig
    71   val hide_classes: bool -> string list -> tsig -> tsig
    72   val set_defsort: sort -> tsig -> tsig
    73   val add_types: NameSpace.naming -> (bstring * int) list -> tsig -> tsig
    74   val add_abbrevs: NameSpace.naming -> (string * string list * typ) list -> tsig -> tsig
    75   val add_nonterminals: NameSpace.naming -> string list -> tsig -> tsig
    76   val hide_types: bool -> string list -> tsig -> tsig
    77   val add_arity: Pretty.pp -> arity -> tsig -> tsig
    78   val add_classrel: Pretty.pp -> class * class -> tsig -> tsig
    79   val merge_tsigs: Pretty.pp -> tsig * tsig -> tsig
    80 end;
    81 
    82 structure Type: TYPE =
    83 struct
    84 
    85 (** type signatures and certified types **)
    86 
    87 (* type declarations *)
    88 
    89 datatype decl =
    90   LogicalType of int |
    91   Abbreviation of string list * typ * bool |
    92   Nonterminal;
    93 
    94 fun str_of_decl (LogicalType _) = "logical type constructor"
    95   | str_of_decl (Abbreviation _) = "type abbreviation"
    96   | str_of_decl Nonterminal = "syntactic type";
    97 
    98 
    99 (* type tsig *)
   100 
   101 datatype tsig =
   102   TSig of {
   103     classes: NameSpace.T * Sorts.algebra,   (*order-sorted algebra of type classes*)
   104     default: sort,                          (*default sort on input*)
   105     types: (decl * serial) NameSpace.table, (*declared types*)
   106     log_types: string list,                 (*logical types sorted by number of arguments*)
   107     witness: (typ * sort) option};          (*witness for non-emptiness of strictest sort*)
   108 
   109 fun rep_tsig (TSig comps) = comps;
   110 
   111 fun make_tsig (classes, default, types, log_types, witness) =
   112   TSig {classes = classes, default = default, types = types,
   113     log_types = log_types, witness = witness};
   114 
   115 fun build_tsig ((space, classes), default, types) =
   116   let
   117     val log_types =
   118       Symtab.fold (fn (c, (LogicalType n, _)) => cons (c, n) | _ => I) (snd types) []
   119       |> Library.sort (Library.int_ord o pairself snd) |> map fst;
   120     val witness =
   121       (case Sorts.witness_sorts classes log_types [] [Sorts.minimal_classes classes] of
   122         [w] => SOME w | _ => NONE);
   123   in make_tsig ((space, classes), default, types, log_types, witness) end;
   124 
   125 fun map_tsig f (TSig {classes, default, types, log_types = _, witness = _}) =
   126   build_tsig (f (classes, default, types));
   127 
   128 val empty_tsig =
   129   build_tsig ((NameSpace.empty, Sorts.empty_algebra), [], NameSpace.empty_table);
   130 
   131 
   132 (* classes and sorts *)
   133 
   134 fun defaultS (TSig {default, ...}) = default;
   135 fun logical_types (TSig {log_types, ...}) = log_types;
   136 fun universal_witness (TSig {witness, ...}) = witness;
   137 
   138 fun eq_sort (TSig {classes, ...}) = Sorts.sort_eq (#2 classes);
   139 fun subsort (TSig {classes, ...}) = Sorts.sort_le (#2 classes);
   140 fun of_sort (TSig {classes, ...}) = Sorts.of_sort (#2 classes);
   141 fun inter_sort (TSig {classes, ...}) = Sorts.inter_sort (#2 classes);
   142 
   143 fun cert_class (TSig {classes, ...}) = Sorts.certify_class (#2 classes);
   144 fun cert_sort (TSig {classes, ...}) = Sorts.certify_sort (#2 classes);
   145 
   146 fun witness_sorts (tsig as TSig {classes, log_types, ...}) =
   147   Sorts.witness_sorts (#2 classes) log_types;
   148 
   149 
   150 (* certification mode *)
   151 
   152 datatype mode = Mode of {normalize: bool, logical: bool};
   153 
   154 val mode_default = Mode {normalize = true, logical = true};
   155 val mode_syntax = Mode {normalize = true, logical = false};
   156 val mode_abbrev = Mode {normalize = false, logical = false};
   157 
   158 
   159 (* certified types *)
   160 
   161 fun bad_nargs t = "Bad number of arguments for type constructor: " ^ quote t;
   162 fun undecl_type c = "Undeclared type constructor: " ^ quote c;
   163 
   164 local
   165 
   166 fun inst_typ env (Type (c, Ts)) = Type (c, map (inst_typ env) Ts)
   167   | inst_typ env (T as TFree (x, _)) = the_default T (AList.lookup (op =) env x)
   168   | inst_typ _ T = T;
   169 
   170 in
   171 
   172 fun cert_typ_mode (Mode {normalize, logical}) tsig ty =
   173   let
   174     val TSig {types = (_, types), ...} = tsig;
   175     fun err msg = raise TYPE (msg, [ty], []);
   176 
   177     val check_logical =
   178       if logical then fn c => err ("Illegal occurrence of syntactic type: " ^ quote c)
   179       else fn _ => ();
   180 
   181     fun cert (T as Type (c, Ts)) =
   182           let
   183             val Ts' = map cert Ts;
   184             fun nargs n = if length Ts <> n then err (bad_nargs c) else ();
   185           in
   186             (case Symtab.lookup types c of
   187               SOME (LogicalType n, _) => (nargs n; Type (c, Ts'))
   188             | SOME (Abbreviation (vs, U, syn), _) =>
   189                (nargs (length vs);
   190                 if syn then check_logical c else ();
   191                 if normalize then inst_typ (vs ~~ Ts') U
   192                 else Type (c, Ts'))
   193             | SOME (Nonterminal, _) => (nargs 0; check_logical c; T)
   194             | NONE => err (undecl_type c))
   195           end
   196       | cert (TFree (x, S)) = TFree (x, cert_sort tsig S)
   197       | cert (TVar (xi as (_, i), S)) =
   198           if i < 0 then
   199             err ("Malformed type variable: " ^ quote (Term.string_of_vname xi))
   200           else TVar (xi, cert_sort tsig S);
   201 
   202     val ty' = cert ty;
   203   in if ty = ty' then ty else ty' end;  (*avoid copying of already normal type*)
   204 
   205 val cert_typ = cert_typ_mode mode_default;
   206 
   207 end;
   208 
   209 
   210 (* type arities *)
   211 
   212 fun arity_number (TSig {types = (_, types), ...}) a =
   213   (case Symtab.lookup types a of
   214     SOME (LogicalType n, _) => n
   215   | _ => error (undecl_type a));
   216 
   217 fun arity_sorts _ tsig a [] = replicate (arity_number tsig a) []
   218   | arity_sorts pp (TSig {classes, ...}) a S = Sorts.mg_domain (#2 classes) a S
   219       handle Sorts.CLASS_ERROR err => Sorts.class_error pp err;
   220 
   221 
   222 
   223 (** special treatment of type vars **)
   224 
   225 (* strip_sorts *)
   226 
   227 fun strip_sorts (Type (a, Ts)) = Type (a, map strip_sorts Ts)
   228   | strip_sorts (TFree (x, _)) = TFree (x, [])
   229   | strip_sorts (TVar (xi, _)) = TVar (xi, []);
   230 
   231 
   232 (* no_tvars *)
   233 
   234 fun no_tvars T =
   235   (case typ_tvars T of [] => T
   236   | vs => raise TYPE ("Illegal schematic type variable(s): " ^
   237       commas_quote (map (Term.string_of_vname o #1) vs), [T], []));
   238 
   239 
   240 (* varify *)
   241 
   242 fun varify fixed t =
   243   let
   244     val fs = Term.fold_types (Term.fold_atyps
   245       (fn TFree v => if member (op =) fixed v then I else insert (op =) v | _ => I)) t [];
   246     val ixns = add_term_tvar_ixns (t, []);
   247     val fmap = fs ~~ map (rpair 0) (Name.variant_list (map #1 ixns) (map fst fs))
   248     fun thaw (f as (a, S)) =
   249       (case AList.lookup (op =) fmap f of
   250         NONE => TFree f
   251       | SOME xi => TVar (xi, S));
   252   in (fmap, map_types (map_type_tfree thaw) t) end;
   253 
   254 
   255 (* freeze_thaw: freeze TVars in a term; return the "thaw" inverse *)
   256 
   257 local
   258 
   259 fun new_name (ix, (pairs, used)) =
   260   let val v = Name.variant used (string_of_indexname ix)
   261   in ((ix, v) :: pairs, v :: used) end;
   262 
   263 fun freeze_one alist (ix, sort) =
   264   TFree (the (AList.lookup (op =) alist ix), sort)
   265     handle Option =>
   266       raise TYPE ("Failure during freezing of ?" ^ string_of_indexname ix, [], []);
   267 
   268 fun thaw_one alist (a, sort) = TVar (the (AList.lookup (op =) alist a), sort)
   269   handle Option => TFree (a, sort);
   270 
   271 in
   272 
   273 (*this sort of code could replace unvarifyT*)
   274 fun freeze_thaw_type T =
   275   let
   276     val used = add_typ_tfree_names (T, [])
   277     and tvars = map #1 (add_typ_tvars (T, []));
   278     val (alist, _) = List.foldr new_name ([], used) tvars;
   279   in (map_type_tvar (freeze_one alist) T, map_type_tfree (thaw_one (map swap alist))) end;
   280 
   281 val freeze_type = #1 o freeze_thaw_type;
   282 
   283 fun freeze_thaw t =
   284   let
   285     val used = it_term_types add_typ_tfree_names (t, [])
   286     and tvars = map #1 (it_term_types add_typ_tvars (t, []));
   287     val (alist, _) = List.foldr new_name ([], used) tvars;
   288   in
   289     (case alist of
   290       [] => (t, fn x => x) (*nothing to do!*)
   291     | _ => (map_types (map_type_tvar (freeze_one alist)) t,
   292       map_types (map_type_tfree (thaw_one (map swap alist)))))
   293   end;
   294 
   295 val freeze = #1 o freeze_thaw;
   296 
   297 end;
   298 
   299 
   300 
   301 (** matching and unification of types **)
   302 
   303 type tyenv = (sort * typ) Vartab.table;
   304 
   305 fun tvar_clash ixn S S' = raise TYPE ("Type variable " ^
   306   quote (Term.string_of_vname ixn) ^ " has two distinct sorts",
   307   [TVar (ixn, S), TVar (ixn, S')], []);
   308 
   309 fun lookup (tye, (ixn, S)) =
   310   (case Vartab.lookup tye ixn of
   311     NONE => NONE
   312   | SOME (S', T) => if S = S' then SOME T else tvar_clash ixn S S');
   313 
   314 
   315 (* matching *)
   316 
   317 exception TYPE_MATCH;
   318 
   319 fun typ_match tsig =
   320   let
   321     fun match (TVar (v, S), T) subs =
   322           (case lookup (subs, (v, S)) of
   323             NONE =>
   324               if of_sort tsig (T, S) then Vartab.update_new (v, (S, T)) subs
   325               else raise TYPE_MATCH
   326           | SOME U => if U = T then subs else raise TYPE_MATCH)
   327       | match (Type (a, Ts), Type (b, Us)) subs =
   328           if a <> b then raise TYPE_MATCH
   329           else matches (Ts, Us) subs
   330       | match (TFree x, TFree y) subs =
   331           if x = y then subs else raise TYPE_MATCH
   332       | match _ _ = raise TYPE_MATCH
   333     and matches (T :: Ts, U :: Us) subs = matches (Ts, Us) (match (T, U) subs)
   334       | matches _ subs = subs;
   335   in match end;
   336 
   337 fun typ_instance tsig (T, U) =
   338   (typ_match tsig (U, T) Vartab.empty; true) handle TYPE_MATCH => false;
   339 
   340 (*purely structural matching*)
   341 fun raw_match (TVar (v, S), T) subs =
   342       (case lookup (subs, (v, S)) of
   343         NONE => Vartab.update_new (v, (S, T)) subs
   344       | SOME U => if U = T then subs else raise TYPE_MATCH)
   345   | raw_match (Type (a, Ts), Type (b, Us)) subs =
   346       if a <> b then raise TYPE_MATCH
   347       else raw_matches (Ts, Us) subs
   348   | raw_match (TFree x, TFree y) subs =
   349       if x = y then subs else raise TYPE_MATCH
   350   | raw_match _ _ = raise TYPE_MATCH
   351 and raw_matches (T :: Ts, U :: Us) subs = raw_matches (Ts, Us) (raw_match (T, U) subs)
   352   | raw_matches ([], []) subs = subs
   353   | raw_matches _ _ = raise TYPE_MATCH;
   354 
   355 fun raw_instance (T, U) =
   356   (raw_match (U, T) Vartab.empty; true) handle TYPE_MATCH => false;
   357 
   358 
   359 (* unification *)
   360 
   361 exception TUNIFY;
   362 
   363 (*occurs_check*)
   364 fun occurs v tye =
   365   let
   366     fun occ (Type (_, Ts)) = exists occ Ts
   367       | occ (TFree _) = false
   368       | occ (TVar (w, S)) =
   369           eq_ix (v, w) orelse
   370             (case lookup (tye, (w, S)) of
   371               NONE => false
   372             | SOME U => occ U);
   373   in occ end;
   374 
   375 (*chase variable assignments; if devar returns a type var then it must be unassigned*)
   376 fun devar tye (T as TVar v) =
   377       (case lookup (tye, v) of
   378         SOME U => devar tye U
   379       | NONE => T)
   380   | devar tye T = T;
   381 
   382 (*order-sorted unification*)
   383 fun unify (tsig as TSig {classes = (_, classes), ...}) TU (tyenv, maxidx) =
   384   let
   385     val tyvar_count = ref maxidx;
   386     fun gen_tyvar S = TVar (("'a", inc tyvar_count), S);
   387 
   388     fun mg_domain a S = Sorts.mg_domain classes a S
   389       handle Sorts.CLASS_ERROR _ => raise TUNIFY;
   390 
   391     fun meet (_, []) tye = tye
   392       | meet (TVar (xi, S'), S) tye =
   393           if Sorts.sort_le classes (S', S) then tye
   394           else Vartab.update_new
   395             (xi, (S', gen_tyvar (Sorts.inter_sort classes (S', S)))) tye
   396       | meet (TFree (_, S'), S) tye =
   397           if Sorts.sort_le classes (S', S) then tye
   398           else raise TUNIFY
   399       | meet (Type (a, Ts), S) tye = meets (Ts, mg_domain a S) tye
   400     and meets (T :: Ts, S :: Ss) tye = meets (Ts, Ss) (meet (devar tye T, S) tye)
   401       | meets _ tye = tye;
   402 
   403     fun unif (ty1, ty2) tye =
   404       (case (devar tye ty1, devar tye ty2) of
   405         (T as TVar (v, S1), U as TVar (w, S2)) =>
   406           if eq_ix (v, w) then
   407             if S1 = S2 then tye else tvar_clash v S1 S2
   408           else if Sorts.sort_le classes (S1, S2) then
   409             Vartab.update_new (w, (S2, T)) tye
   410           else if Sorts.sort_le classes (S2, S1) then
   411             Vartab.update_new (v, (S1, U)) tye
   412           else
   413             let val S = gen_tyvar (Sorts.inter_sort classes (S1, S2)) in
   414               Vartab.update_new (v, (S1, S)) (Vartab.update_new (w, (S2, S)) tye)
   415             end
   416       | (TVar (v, S), T) =>
   417           if occurs v tye T then raise TUNIFY
   418           else meet (T, S) (Vartab.update_new (v, (S, T)) tye)
   419       | (T, TVar (v, S)) =>
   420           if occurs v tye T then raise TUNIFY
   421           else meet (T, S) (Vartab.update_new (v, (S, T)) tye)
   422       | (Type (a, Ts), Type (b, Us)) =>
   423           if a <> b then raise TUNIFY
   424           else unifs (Ts, Us) tye
   425       | (T, U) => if T = U then tye else raise TUNIFY)
   426     and unifs (T :: Ts, U :: Us) tye = unifs (Ts, Us) (unif (T, U) tye)
   427       | unifs _ tye = tye;
   428   in (unif TU tyenv, ! tyvar_count) end;
   429 
   430 (*purely structural unification*)
   431 fun raw_unify (ty1, ty2) tye =
   432   (case (devar tye ty1, devar tye ty2) of
   433     (T as TVar (v, S1), U as TVar (w, S2)) =>
   434       if eq_ix (v, w) then
   435         if S1 = S2 then tye else tvar_clash v S1 S2
   436       else Vartab.update_new (w, (S2, T)) tye
   437   | (TVar (v, S), T) =>
   438       if occurs v tye T then raise TUNIFY
   439       else Vartab.update_new (v, (S, T)) tye
   440   | (T, TVar (v, S)) =>
   441       if occurs v tye T then raise TUNIFY
   442       else Vartab.update_new (v, (S, T)) tye
   443   | (Type (a, Ts), Type (b, Us)) =>
   444       if a <> b then raise TUNIFY
   445       else raw_unifys (Ts, Us) tye
   446   | (T, U) => if T = U then tye else raise TUNIFY)
   447 and raw_unifys (T :: Ts, U :: Us) tye = raw_unifys (Ts, Us) (raw_unify (T, U) tye)
   448   | raw_unifys ([], []) tye = tye
   449   | raw_unifys _ _ = raise TUNIFY;
   450 
   451 (*fast unification filter*)
   452 fun could_unify (Type (a, Ts), Type (b, Us)) = a = b andalso could_unifys (Ts, Us)
   453   | could_unify (TFree (a, _), TFree (b, _)) = a = b
   454   | could_unify (TVar _, _) = true
   455   | could_unify (_, TVar _) = true
   456   | could_unify _ = false
   457 and could_unifys (T :: Ts, U :: Us) = could_unify (T, U) andalso could_unifys (Ts, Us)
   458   | could_unifys ([], []) = true
   459   | could_unifys _ = false;
   460 
   461 
   462 (*equality with respect to a type environment*)
   463 fun eq_type tye (T, T') =
   464   (case (devar tye T, devar tye T') of
   465      (Type (s, Ts), Type (s', Ts')) =>
   466        s = s' andalso ListPair.all (eq_type tye) (Ts, Ts')
   467    | (U, U') => U = U');
   468 
   469 
   470 
   471 (** extend and merge type signatures **)
   472 
   473 (* classes *)
   474 
   475 fun add_class pp naming (c, cs) tsig =
   476   tsig |> map_tsig (fn ((space, classes), default, types) =>
   477     let
   478       val c' = NameSpace.full naming c;
   479       val cs' = map (cert_class tsig) cs
   480         handle TYPE (msg, _, _) => error msg;
   481       val space' = space |> NameSpace.declare naming c';
   482       val classes' = classes |> Sorts.add_class pp (c', cs');
   483     in ((space', classes'), default, types) end);
   484 
   485 fun hide_classes fully cs = map_tsig (fn ((space, classes), default, types) =>
   486   ((fold (NameSpace.hide fully) cs space, classes), default, types));
   487 
   488 
   489 (* arities *)
   490 
   491 fun add_arity pp (t, Ss, S) tsig = tsig |> map_tsig (fn ((space, classes), default, types) =>
   492   let
   493     val _ =
   494       (case Symtab.lookup (#2 types) t of
   495         SOME (LogicalType n, _) => if length Ss <> n then error (bad_nargs t) else ()
   496       | SOME (decl, _) => error ("Illegal " ^ str_of_decl decl ^ ": " ^ quote t)
   497       | NONE => error (undecl_type t));
   498     val (Ss', S') = (map (cert_sort tsig) Ss, cert_sort tsig S)
   499       handle TYPE (msg, _, _) => error msg;
   500     val classes' = classes |> Sorts.add_arities pp ((t, map (fn c' => (c', Ss')) S'));
   501   in ((space, classes'), default, types) end);
   502 
   503 
   504 (* classrel *)
   505 
   506 fun add_classrel pp rel tsig =
   507   tsig |> map_tsig (fn ((space, classes), default, types) =>
   508     let
   509       val rel' = pairself (cert_class tsig) rel
   510         handle TYPE (msg, _, _) => error msg;
   511       val classes' = classes |> Sorts.add_classrel pp rel;
   512     in ((space, classes'), default, types) end);
   513 
   514 
   515 (* default sort *)
   516 
   517 fun set_defsort S tsig = tsig |> map_tsig (fn (classes, _, types) =>
   518   (classes, cert_sort tsig S handle TYPE (msg, _, _) => error msg, types));
   519 
   520 
   521 (* types *)
   522 
   523 local
   524 
   525 fun err_neg_args c =
   526   error ("Negative number of arguments in type constructor declaration: " ^ quote c);
   527 
   528 fun err_in_decls c decl decl' =
   529   let val s = str_of_decl decl and s' = str_of_decl decl' in
   530     if s = s' then error ("Duplicate declaration of " ^ s ^ ": " ^ quote c)
   531     else error ("Conflict of " ^ s ^ " with " ^ s' ^ ": " ^ quote c)
   532   end;
   533 
   534 fun new_decl naming (c, decl) (space, types) =
   535   let
   536     val c' = NameSpace.full naming c;
   537     val space' = NameSpace.declare naming c' space;
   538     val types' =
   539       (case Symtab.lookup types c' of
   540         SOME (decl', _) => err_in_decls c' decl decl'
   541       | NONE => Symtab.update (c', (decl, serial ())) types);
   542   in (space', types') end;
   543 
   544 fun the_decl (_, types) = fst o the o Symtab.lookup types;
   545 
   546 fun map_types f = map_tsig (fn (classes, default, types) =>
   547   let
   548     val (space', tab') = f types;
   549     val _ = NameSpace.intern space' "dummy" = "dummy" orelse
   550       error "Illegal declaration of dummy type";
   551   in (classes, default, (space', tab')) end);
   552 
   553 fun syntactic types (Type (c, Ts)) =
   554       (case Symtab.lookup types c of SOME (Nonterminal, _) => true | _ => false)
   555         orelse exists (syntactic types) Ts
   556   | syntactic _ _ = false;
   557 
   558 fun add_abbrev naming (a, vs, rhs) tsig = tsig |> map_types (fn types =>
   559   let
   560     fun err msg = cat_error msg ("The error(s) above occurred in type abbreviation: " ^ quote a);
   561     val rhs' = strip_sorts (no_tvars (cert_typ_mode mode_syntax tsig rhs))
   562       handle TYPE (msg, _, _) => err msg;
   563   in
   564     (case duplicates (op =) vs of
   565       [] => []
   566     | dups => err ("Duplicate variables on lhs: " ^ commas_quote dups));
   567     (case subtract (op =) vs (map (#1 o #1) (typ_tvars rhs')) of
   568       [] => []
   569     | extras => err ("Extra variables on rhs: " ^ commas_quote extras));
   570     types |> new_decl naming (a, Abbreviation (vs, rhs', syntactic (#2 types) rhs'))
   571   end);
   572 
   573 in
   574 
   575 fun add_types naming ps = map_types (fold (new_decl naming) (ps |> map (fn (c, n) =>
   576   if n < 0 then err_neg_args c else (c, LogicalType n))));
   577 
   578 val add_abbrevs = fold o add_abbrev;
   579 
   580 fun add_nonterminals naming = map_types o fold (new_decl naming) o map (rpair Nonterminal);
   581 
   582 fun merge_types (types1, types2) =
   583   NameSpace.merge_tables (Library.eq_snd (op = : serial * serial -> bool)) (types1, types2)
   584     handle Symtab.DUP d => err_in_decls d (the_decl types1 d) (the_decl types2 d);
   585 
   586 end;
   587 
   588 fun hide_types fully cs = map_tsig (fn (classes, default, (space, types)) =>
   589   (classes, default, (fold (NameSpace.hide fully) cs space, types)));
   590 
   591 
   592 (* merge type signatures *)
   593 
   594 fun merge_tsigs pp (tsig1, tsig2) =
   595   let
   596     val (TSig {classes = (space1, classes1), default = default1, types = types1,
   597       log_types = _, witness = _}) = tsig1;
   598     val (TSig {classes = (space2, classes2), default = default2, types = types2,
   599       log_types = _, witness = _}) = tsig2;
   600 
   601     val space' = NameSpace.merge (space1, space2);
   602     val classes' = Sorts.merge_algebra pp (classes1, classes2);
   603     val default' = Sorts.inter_sort classes' (default1, default2);
   604     val types' = merge_types (types1, types2);
   605   in build_tsig ((space', classes'), default', types') end;
   606 
   607 end;