1 (* Title: Pure/sign.ML |
1 (* Title: Pure/sign.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
3 Author: Lawrence C Paulson and Markus Wenzel |
4 Copyright 1994 University of Cambridge |
4 |
5 |
5 The abstract type "sg" of signatures. |
6 The abstract types "sg" of signatures |
6 |
|
7 TODO: |
|
8 a clean modular sequential Sign.extend (using sg_ext list); |
7 *) |
9 *) |
8 |
10 |
9 signature SIGN = |
11 signature SIGN = |
10 sig |
12 sig |
11 structure Type: TYPE |
|
12 structure Symtab: SYMTAB |
13 structure Symtab: SYMTAB |
13 structure Syntax: SYNTAX |
14 structure Syntax: SYNTAX |
|
15 structure Type: TYPE |
14 sharing Symtab = Type.Symtab |
16 sharing Symtab = Type.Symtab |
15 type sg |
17 local open Type in |
16 val extend: sg -> string -> |
18 type sg |
17 (class * class list) list * class list * |
19 val rep_sg: sg -> |
18 (string list * int) list * |
20 {tsig: type_sig, |
19 (string * indexname list * string) list * |
21 const_tab: typ Symtab.table, |
20 (string list * (sort list * class)) list * |
22 syn: Syntax.syntax, |
21 (string list * string)list * Syntax.sext option -> sg |
23 stamps: string ref list} |
22 val merge: sg * sg -> sg |
24 val subsig: sg * sg -> bool |
23 val pure: sg |
25 val eq_sg: sg * sg -> bool |
24 val read_typ: sg * (indexname -> sort option) -> string -> typ |
26 val print_sg: sg -> unit |
25 val rep_sg: sg -> {tsig: Type.type_sig, |
27 val pprint_sg: sg -> pprint_args -> unit |
26 const_tab: typ Symtab.table, |
28 val pretty_term: sg -> term -> Syntax.Pretty.T |
27 syn: Syntax.syntax, |
29 val pretty_typ: sg -> typ -> Syntax.Pretty.T |
28 stamps: string ref list} |
30 val string_of_term: sg -> term -> string |
29 val string_of_term: sg -> term -> string |
31 val string_of_typ: sg -> typ -> string |
30 val string_of_typ: sg -> typ -> string |
32 val pprint_term: sg -> term -> pprint_args -> unit |
31 val subsig: sg * sg -> bool |
33 val pprint_typ: sg -> typ -> pprint_args -> unit |
32 val pprint_term: sg -> term -> pprint_args -> unit |
34 val certify_typ: sg -> typ -> typ |
33 val pprint_typ: sg -> typ -> pprint_args -> unit |
35 val certify_term: sg -> term -> term * typ * int |
34 val pretty_term: sg -> term -> Syntax.Pretty.T |
36 val read_typ: sg * (indexname -> sort option) -> string -> typ |
35 val term_errors: sg -> term -> string list |
37 val extend: sg -> string -> |
|
38 (class * class list) list * class list * |
|
39 (string list * int) list * |
|
40 (string * string list * string) list * |
|
41 (string list * (sort list * class)) list * |
|
42 (string list * string) list * Syntax.sext option -> sg |
|
43 val merge: sg * sg -> sg |
|
44 val pure: sg |
|
45 end |
36 end; |
46 end; |
37 |
47 |
38 functor SignFun(structure Type: TYPE and Syntax: SYNTAX) : SIGN = |
48 functor SignFun(structure Syntax: SYNTAX and Type: TYPE): SIGN = |
39 struct |
49 struct |
40 |
50 |
41 structure Type = Type; |
|
42 structure Symtab = Type.Symtab; |
51 structure Symtab = Type.Symtab; |
43 structure Syntax = Syntax; |
52 structure Syntax = Syntax; |
44 structure Pretty = Syntax.Pretty |
53 structure Pretty = Syntax.Pretty; |
45 |
54 structure Type = Type; |
46 |
55 open Type; |
47 (* Signatures of theories. *) |
56 |
|
57 |
|
58 (** datatype sg **) |
|
59 |
|
60 (*the "ref" in stamps ensures that no two signatures are identical -- it is |
|
61 impossible to forge a signature*) |
48 |
62 |
49 datatype sg = |
63 datatype sg = |
50 Sg of { |
64 Sg of { |
51 tsig: Type.type_sig, (*order-sorted signature of types*) |
65 tsig: type_sig, (*order-sorted signature of types*) |
52 const_tab: typ Symtab.table, (*types of constants*) |
66 const_tab: typ Symtab.table, (*types of constants*) |
53 syn: Syntax.syntax, (*syntax for parsing and printing*) |
67 syn: Syntax.syntax, (*syntax for parsing and printing*) |
54 stamps: string ref list}; (*unique theory indentifier*) |
68 stamps: string ref list}; (*unique theory indentifier*) |
55 |
69 |
56 |
|
57 fun rep_sg (Sg args) = args; |
70 fun rep_sg (Sg args) = args; |
58 |
71 |
59 fun subsig(Sg{stamps=s1,...},Sg{stamps=s2,...}) = s1 subset s2; |
72 |
60 |
73 fun subsig (Sg {stamps = s1, ...}, Sg {stamps = s2, ...}) = s1 subset s2; |
61 fun string_of_typ(Sg{tsig,syn,...}) = Syntax.string_of_typ syn; |
74 |
62 |
75 fun eq_sg (sg1, sg2) = subsig (sg1, sg2) andalso subsig (sg2, sg1); |
63 fun pprint_typ(Sg{syn,...}) = Pretty.pprint o Pretty.quote o (Syntax.pretty_typ syn); |
76 |
64 |
77 |
65 (*Is constant present in table with more generic type?*) |
78 |
66 fun valid_const tsig ctab (a,T) = case Symtab.lookup(ctab, a) of |
79 (** print signature **) |
67 Some U => Type.typ_instance(tsig,T,U) | _ => false; |
80 |
68 |
81 fun print_sg sg = |
69 |
|
70 (*Check a term for errors. Are all constants and types valid in signature? |
|
71 Does not check that term is well-typed!*) |
|
72 fun term_errors (sign as Sg{tsig,const_tab,...}) = |
|
73 let val showtyp = string_of_typ sign |
|
74 fun terrs (Const (a,T), errs) = |
|
75 if valid_const tsig const_tab (a,T) |
|
76 then Type.type_errors tsig (T,errs) |
|
77 else ("Illegal type for constant: " ^ a ^ ": " ^ showtyp T) :: errs |
|
78 | terrs (Free (_,T), errs) = Type.type_errors tsig (T,errs) |
|
79 | terrs (Var ((a,i),T), errs) = |
|
80 if i>=0 then Type.type_errors tsig (T,errs) |
|
81 else ("Negative index for Var: " ^ a) :: errs |
|
82 | terrs (Bound _, errs) = errs (*loose bvars detected by type_of*) |
|
83 | terrs (Abs (_,T,t), errs) = |
|
84 Type.type_errors tsig (T,terrs(t,errs)) |
|
85 | terrs (f$t, errs) = terrs(f, terrs (t,errs)) |
|
86 in fn t => terrs(t,[]) end; |
|
87 |
|
88 |
|
89 |
|
90 (** The Extend operation **) |
|
91 |
|
92 (* Extend a signature: may add classes, types and constants. The "ref" in |
|
93 stamps ensures that no two signatures are identical -- it is impossible to |
|
94 forge a signature. *) |
|
95 |
|
96 fun extend (Sg {tsig, const_tab, syn, stamps}) name |
|
97 (classes, default, types, abbr, arities, const_decs, opt_sext) = |
|
98 let |
82 let |
99 fun err_in_typ s = error ("The error(s) above occurred in type " ^ quote s); |
83 fun prt_typ syn ty = Pretty.quote (Syntax.pretty_typ syn ty); |
100 |
84 |
101 fun read_typ tsg sy s = |
85 fun pretty_sort [cl] = Pretty.str cl |
102 Syntax.read_typ sy (K (Type.defaultS tsg)) s handle ERROR => err_in_typ s; |
86 | pretty_sort cls = Pretty.str_list "{" "}" cls; |
103 |
87 |
104 fun check_typ tsg sy ty = |
88 fun pretty_subclass (cl, cls) = Pretty.block |
105 (case Type.type_errors tsg (ty, []) of |
89 [Pretty.str (cl ^ " <"), Pretty.brk 1, pretty_sort cls]; |
106 [] => ty |
90 |
107 | errs => (prs (cat_lines errs); err_in_typ (Syntax.string_of_typ sy ty))); |
91 fun pretty_default cls = Pretty.block |
108 |
92 [Pretty.str "default:", Pretty.brk 1, pretty_sort cls]; |
109 (*reset TVar indices to zero, renaming to preserve distinctness*) |
93 |
110 fun zero_tvar_indices T = |
94 fun pretty_arg (ty, n) = Pretty.str (ty ^ " " ^ string_of_int n); |
|
95 |
|
96 fun pretty_abbr syn (ty, (vs, rhs)) = Pretty.block |
|
97 [prt_typ syn (Type (ty, map (fn v => TVar (v, [])) vs)), |
|
98 Pretty.str " =", Pretty.brk 1, prt_typ syn rhs]; |
|
99 |
|
100 fun pretty_arity ty (cl, []) = Pretty.block |
|
101 [Pretty.str (ty ^ " ::"), Pretty.brk 1, Pretty.str cl] |
|
102 | pretty_arity ty (cl, srts) = Pretty.block |
|
103 [Pretty.str (ty ^ " ::"), Pretty.brk 1, |
|
104 Pretty.list "(" ")" (map pretty_sort srts), |
|
105 Pretty.brk 1, Pretty.str cl]; |
|
106 |
|
107 fun pretty_coreg (ty, ars) = map (pretty_arity ty) ars; |
|
108 |
|
109 fun pretty_const syn (c, ty) = Pretty.block |
|
110 [Pretty.str (c ^ " ::"), Pretty.brk 1, prt_typ syn ty]; |
|
111 |
|
112 |
|
113 val Sg {tsig, const_tab, syn, stamps} = sg; |
|
114 val {classes, subclass, default, args, abbrs, coreg} = rep_tsig tsig; |
|
115 in |
|
116 Pretty.writeln (Pretty.strs ("stamps:" :: map ! stamps)); |
|
117 Pretty.writeln (Pretty.strs ("classes:" :: classes)); |
|
118 Pretty.writeln (Pretty.big_list "subclass:" (map pretty_subclass subclass)); |
|
119 Pretty.writeln (pretty_default default); |
|
120 Pretty.writeln (Pretty.big_list "types:" (map pretty_arg args)); |
|
121 Pretty.writeln (Pretty.big_list "abbrs:" (map (pretty_abbr syn) abbrs)); |
|
122 Pretty.writeln (Pretty.big_list "coreg:" (flat (map pretty_coreg coreg))); |
|
123 Pretty.writeln (Pretty.big_list "consts:" |
|
124 (map (pretty_const syn) (Symtab.alist_of const_tab))) |
|
125 end; |
|
126 |
|
127 |
|
128 fun pprint_sg (Sg {stamps, ...}) = |
|
129 Pretty.pprint (Pretty.str_list "{" "}" (map ! stamps)); |
|
130 |
|
131 |
|
132 |
|
133 (** pretty printing of terms and types **) |
|
134 |
|
135 fun pretty_term (Sg {syn, ...}) = Syntax.pretty_term syn; |
|
136 fun pretty_typ (Sg {syn, ...}) = Syntax.pretty_typ syn; |
|
137 |
|
138 fun string_of_term (Sg {syn, ...}) = Syntax.string_of_term syn; |
|
139 fun string_of_typ (Sg {syn, ...}) = Syntax.string_of_typ syn; |
|
140 |
|
141 fun pprint_term sg = Pretty.pprint o Pretty.quote o (pretty_term sg); |
|
142 fun pprint_typ sg = Pretty.pprint o Pretty.quote o (pretty_typ sg); |
|
143 |
|
144 |
|
145 |
|
146 (** certify types and terms **) |
|
147 |
|
148 (*errors are indicated by exception TYPE*) |
|
149 |
|
150 fun certify_typ (Sg {tsig, ...}) ty = cert_typ tsig ty; |
|
151 |
|
152 |
|
153 (* FIXME -> term.ML (?) *) |
|
154 fun mapfilter_atoms f (Abs (_, _, t)) = mapfilter_atoms f t |
|
155 | mapfilter_atoms f (t $ u) = mapfilter_atoms f t @ mapfilter_atoms f u |
|
156 | mapfilter_atoms f a = (case f a of Some y => [y] | None => []); |
|
157 |
|
158 fun certify_term (sg as Sg {tsig, const_tab, ...}) tm = |
|
159 let |
|
160 fun valid_const a T = |
|
161 (case Symtab.lookup (const_tab, a) of |
|
162 Some U => typ_instance (tsig, T, U) |
|
163 | _ => false); |
|
164 |
|
165 fun atom_err (Const (a, T)) = |
|
166 if valid_const a T then None |
|
167 else Some ("Illegal type for constant " ^ quote a ^ " :: " ^ |
|
168 quote (string_of_typ sg T)) |
|
169 | atom_err (Var ((x, i), _)) = |
|
170 if i < 0 then Some ("Negative index for Var " ^ quote x) else None |
|
171 | atom_err _ = None; |
|
172 |
|
173 |
|
174 val norm_tm = |
|
175 (case it_term_types (typ_errors tsig) (tm, []) of |
|
176 [] => map_term_types (norm_typ tsig) tm |
|
177 | errs => raise_type (cat_lines errs) [] [tm]); |
|
178 in |
|
179 (case mapfilter_atoms atom_err norm_tm of |
|
180 [] => (norm_tm, type_of norm_tm, maxidx_of_term norm_tm) |
|
181 | errs => raise_type (cat_lines errs) [] [norm_tm]) |
|
182 end; |
|
183 |
|
184 |
|
185 |
|
186 (** read types **) |
|
187 |
|
188 (*read and certify typ wrt a signature; errors are indicated by |
|
189 exception ERROR (with messages already printed)*) |
|
190 |
|
191 fun rd_typ tsig syn sort_of s = |
|
192 let |
|
193 val def_sort = defaultS tsig; |
|
194 val raw_ty = (*this may raise ERROR, too!*) |
|
195 Syntax.read_typ syn (fn x => if_none (sort_of x) def_sort) s; |
|
196 in |
|
197 cert_typ tsig raw_ty |
|
198 handle TYPE (msg, _, _) => error msg |
|
199 end |
|
200 handle ERROR => error ("The error(s) above occurred in type " ^ quote s); |
|
201 |
|
202 fun read_typ (Sg {tsig, syn, ...}, sort_of) s = rd_typ tsig syn sort_of s; |
|
203 |
|
204 |
|
205 |
|
206 (** extend signature **) |
|
207 |
|
208 (*errors are indicated by exception ERROR (with messages already printed)*) |
|
209 |
|
210 fun extend sg name (classes, default, types, abbrs, arities, consts, opt_sext) = |
|
211 let |
|
212 (*reset TVar indices to 0, renaming to preserve distinctness*) |
|
213 fun zero_tvar_idxs T = |
111 let |
214 let |
112 val inxSs = typ_tvars T; |
215 val inxSs = typ_tvars T; |
113 val nms' = variantlist (map (#1 o #1) inxSs, []); |
216 val nms' = variantlist (map (#1 o #1) inxSs, []); |
114 val tye = map (fn ((v, S), a) => (v, TVar ((a, 0), S))) (inxSs ~~ nms'); |
217 val tye = map2 (fn ((v, S), a) => (v, TVar ((a, 0), S))) (inxSs, nms'); |
115 in typ_subst_TVars tye T end; |
218 in |
|
219 typ_subst_TVars tye T |
|
220 end; |
116 |
221 |
117 (*read and check the type mentioned in a const declaration; zero type var |
222 (*read and check the type mentioned in a const declaration; zero type var |
118 indices because type inference requires it*) |
223 indices because type inference requires it*) |
119 |
224 fun read_const tsig syn (c, s) = |
120 fun read_consts tsg sy (cs, s) = |
225 (c, zero_tvar_idxs (varifyT (rd_typ tsig syn (K None) s))) |
121 let val ty = zero_tvar_indices (Type.varifyT (read_typ tsg sy s)); |
226 handle ERROR => error ("in declaration of constant " ^ quote c); |
122 in |
227 |
123 (case Type.type_errors tsg (ty, []) of |
228 fun read_abbr tsig syn (c, vs, rhs_src) = |
124 [] => (cs, ty) |
229 (c, (map (rpair 0) vs, varifyT (rd_typ tsig syn (K None) rhs_src) |
125 | errs => error (cat_lines (("Error in type of constants " ^ |
230 handle ERROR => error ("in type abbreviation " ^ quote c))); |
126 space_implode " " (map quote cs)) :: errs))) |
231 |
127 end; |
232 |
128 |
233 val Sg {tsig, const_tab, syn, stamps} = sg; |
129 val tsig' = Type.extend (tsig, classes, default, types, arities); |
234 val xconsts = map #1 classes @ flat (map #1 types) @ map #1 abbrs @ |
130 |
235 flat (map #1 consts); |
131 fun read_typ_abbr(a,v,s)= |
236 val sext = if_none opt_sext Syntax.empty_sext; |
132 let val T = Type.varifyT(read_typ tsig' syn s) |
237 |
133 in (a,(v,T)) end handle ERROR => error("This error occured in abbreviation "^ quote a); |
238 val tsig' = extend_tsig tsig (classes, default, types, arities); |
134 |
239 val tsig1 = ext_tsig_abbrs tsig' (map (read_abbr tsig' syn) abbrs); |
135 val abbr' = map read_typ_abbr abbr; |
240 |
136 val tsig'' = Type.add_abbrs(tsig',abbr'); |
241 val syn1 = Syntax.extend syn (rd_typ tsig1 syn (K None)) |
137 |
242 (logical_types tsig1, xconsts, sext); |
138 val read_ty = |
243 |
139 (Type.expand_typ tsig'') o (check_typ tsig'' syn) o (read_typ tsig'' syn); |
244 val all_consts = flat (map (fn (cs, s) => map (rpair s) cs) |
140 val log_types = Type.logical_types tsig''; |
245 (Syntax.constants sext @ consts)); |
141 val xconsts = map #1 classes @ flat (map #1 types) @ flat (map #1 const_decs); |
246 |
142 val sext = case opt_sext of Some sx => sx | None => Syntax.empty_sext; |
247 val const_tab1 = (* FIXME bug: vvvv should be syn *) |
143 |
248 Symtab.extend (K false) (const_tab, map (read_const tsig1 syn1) all_consts) |
144 val syn' = Syntax.extend syn read_ty (log_types, xconsts, sext); |
249 handle Symtab.DUPLICATE c |
145 |
250 => error ("Constant " ^ quote c ^ " declared twice"); |
146 val const_decs' = |
251 |
147 map (read_consts tsig'' syn') (Syntax.constants sext @ const_decs); |
252 val stamps1 = |
|
253 if exists (equal name o !) stamps then |
|
254 error ("Theory already contains a " ^ quote name ^ " component") |
|
255 else stamps @ [ref name]; |
148 in |
256 in |
149 Sg { |
257 Sg {tsig = tsig1, const_tab = const_tab1, syn = syn1, stamps = stamps1} |
150 tsig = tsig'', |
|
151 const_tab = Symtab.st_of_declist (const_decs', const_tab) |
|
152 handle Symtab.DUPLICATE a => error ("Constant " ^ quote a ^ " declared twice"), |
|
153 syn = syn', |
|
154 stamps = ref name :: stamps} |
|
155 end; |
258 end; |
156 |
259 |
157 |
260 |
158 (* The empty signature *) |
261 |
159 |
262 (** merge signatures **) |
160 val sg0 = Sg {tsig = Type.tsig0, const_tab = Symtab.null, |
263 |
|
264 (*errors are indicated by exception TERM*) |
|
265 |
|
266 fun check_stamps stamps = |
|
267 (case duplicates (map ! stamps) of |
|
268 [] => stamps |
|
269 | dups => raise_term ("Attempt to merge different versions of theories " ^ |
|
270 commas (map quote dups)) []); |
|
271 |
|
272 fun merge (sg1, sg2) = |
|
273 if subsig (sg2, sg1) then sg1 |
|
274 else if subsig (sg1, sg2) then sg2 |
|
275 else |
|
276 (*neither is union already; must form union*) |
|
277 let |
|
278 val Sg {tsig = tsig1, const_tab = const_tab1, syn = syn1, |
|
279 stamps = stamps1} = sg1; |
|
280 val Sg {tsig = tsig2, const_tab = const_tab2, syn = syn2, |
|
281 stamps = stamps2} = sg2; |
|
282 |
|
283 val tsig = merge_tsigs (tsig1, tsig2); |
|
284 |
|
285 val const_tab = Symtab.merge (op =) (const_tab1, const_tab2) |
|
286 handle Symtab.DUPLICATE c => |
|
287 raise_term ("Incompatible types for constant " ^ quote c) []; |
|
288 |
|
289 val syn = Syntax.merge (logical_types tsig) syn1 syn2; |
|
290 |
|
291 val stamps = check_stamps (merge_lists stamps1 stamps2); |
|
292 in |
|
293 Sg {tsig = tsig, const_tab = const_tab, syn = syn, stamps = stamps} |
|
294 end; |
|
295 |
|
296 |
|
297 |
|
298 (** the Pure signature **) |
|
299 |
|
300 val sg0 = Sg {tsig = tsig0, const_tab = Symtab.null, |
161 syn = Syntax.type_syn, stamps = []}; |
301 syn = Syntax.type_syn, stamps = []}; |
162 |
302 |
163 |
|
164 (* The pure signature *) |
|
165 |
|
166 val pure = extend sg0 "Pure" |
303 val pure = extend sg0 "Pure" |
167 ([("logic", [])], |
304 ([("logic", [])], |
168 ["logic"], |
305 ["logic"], |
169 [(["fun"], 2), |
306 [(["fun"], 2), |
170 (["prop"], 0), |
307 (["prop"], 0), |
171 (Syntax.syntax_types, 0)], |
308 (Syntax.syntax_types, 0)], |
172 [], |
309 [], |
173 [(["fun"], ([["logic"], ["logic"]], "logic")), |
310 [(["fun"], ([["logic"], ["logic"]], "logic")), |
174 (["prop"], ([], "logic"))], |
311 (["prop"], ([], "logic"))], |
175 [([Syntax.constrainC], "'a::logic => 'a")], |
312 ([Syntax.constrainC], "'a::{} => 'a") :: Syntax.syntax_consts, |
176 Some Syntax.pure_sext); |
313 Some Syntax.pure_sext); |
177 |
314 |
178 |
|
179 |
|
180 (** The Merge operation **) |
|
181 |
|
182 (*Update table with (a,x) providing any existing asgt to "a" equals x. *) |
|
183 fun update_eq ((a,x),tab) = |
|
184 case Symtab.lookup(tab,a) of |
|
185 None => Symtab.update((a,x), tab) |
|
186 | Some y => if x=y then tab |
|
187 else raise TERM ("Incompatible types for constant: "^a, []); |
|
188 |
|
189 (*Combine tables, updating tab2 by tab1 and checking.*) |
|
190 fun merge_tabs (tab1,tab2) = |
|
191 Symtab.balance (foldr update_eq (Symtab.alist_of tab1, tab2)); |
|
192 |
|
193 (*Combine tables, overwriting tab2 with tab1.*) |
|
194 fun smash_tabs (tab1,tab2) = |
|
195 Symtab.balance (foldr Symtab.update (Symtab.alist_of tab1, tab2)); |
|
196 |
|
197 (*Combine stamps, checking that theory names are disjoint. *) |
|
198 fun merge_stamps (stamps1,stamps2) = |
|
199 let val stamps = stamps1 union stamps2 in |
|
200 case findrep (map ! stamps) of |
|
201 a::_ => error ("Attempt to merge different versions of theory: " ^ a) |
|
202 | [] => stamps |
|
203 end; |
|
204 |
|
205 (*Merge two signatures. Forms unions of tables. Prefers sign1. *) |
|
206 fun merge |
|
207 (sign1 as Sg {tsig = tsig1, const_tab = ctab1, stamps = stamps1, syn = syn1}, |
|
208 sign2 as Sg {tsig = tsig2, const_tab = ctab2, stamps = stamps2, syn = syn2}) = |
|
209 if stamps2 subset stamps1 then sign1 |
|
210 else if stamps1 subset stamps2 then sign2 |
|
211 else (*neither is union already; must form union*) |
|
212 let val tsig = Type.merge (tsig1, tsig2); |
|
213 in |
|
214 Sg {tsig = tsig, const_tab = merge_tabs (ctab1, ctab2), |
|
215 stamps = merge_stamps (stamps1, stamps2), |
|
216 syn = Syntax.merge (Type.logical_types tsig) syn1 syn2} |
|
217 end; |
|
218 |
|
219 |
|
220 |
|
221 fun read_typ(Sg{tsig,syn,...}, defS) s = |
|
222 let val term = Syntax.read syn Syntax.typeT s; |
|
223 val S0 = Type.defaultS tsig; |
|
224 fun defS0 s = case defS s of Some S => S | None => S0; |
|
225 in Syntax.typ_of_term defS0 term end; |
|
226 |
|
227 (** pretty printing of terms **) |
|
228 |
|
229 fun pretty_term (Sg{tsig,syn,...}) = Syntax.pretty_term syn; |
|
230 |
|
231 fun string_of_term sign t = Pretty.string_of (pretty_term sign t); |
|
232 |
|
233 fun pprint_term sign = Pretty.pprint o Pretty.quote o (pretty_term sign); |
|
234 |
315 |
235 end; |
316 end; |
236 |
317 |