15 structure SMT_Datatypes: SMT_DATATYPES = |
15 structure SMT_Datatypes: SMT_DATATYPES = |
16 struct |
16 struct |
17 |
17 |
18 val lhs_head_of = Term.head_of o fst o Logic.dest_equals o Thm.prop_of |
18 val lhs_head_of = Term.head_of o fst o Logic.dest_equals o Thm.prop_of |
19 |
19 |
20 fun mk_selectors T Ts ctxt = |
20 fun mk_selectors T Ts = |
21 let |
21 Variable.variant_fixes (replicate (length Ts) "select") |
22 val (sels, ctxt') = |
22 #>> map2 (fn U => fn n => Free (n, T --> U)) Ts |
23 Variable.variant_fixes (replicate (length Ts) "select") ctxt |
|
24 in (map2 (fn n => fn U => Free (n, T --> U)) sels Ts, ctxt') end |
|
25 |
23 |
26 |
24 |
27 (* datatype declarations *) |
25 (* free constructor type declarations *) |
28 |
26 |
29 fun get_datatype_decl ({descr, ...} : Datatype.info) n Ts ctxt = |
27 fun get_ctr_sugar_decl ({ctrs, ...} : Ctr_Sugar.ctr_sugar) T Ts ctxt = |
30 let |
28 let |
31 fun get_vars (_, (m, vs, _)) = if m = n then SOME vs else NONE |
29 fun mk_constr ctr0 = |
32 val vars = the (get_first get_vars descr) ~~ Ts |
30 let val ctr = Ctr_Sugar.mk_ctr Ts ctr0 in |
33 val lookup_var = the o AList.lookup (op =) vars |
31 mk_selectors T (binder_types (fastype_of ctr)) #>> pair ctr |
34 |
32 end |
35 fun typ_of (dt as Datatype.DtTFree _) = lookup_var dt |
33 in |
36 | typ_of (Datatype.DtType (m, dts)) = Type (m, map typ_of dts) |
34 fold_map mk_constr ctrs ctxt |
37 | typ_of (Datatype.DtRec i) = |
35 |>> (pair T #> single) |
38 the (AList.lookup (op =) descr i) |
36 end |
39 |> (fn (m, dts, _) => Type (m, map typ_of dts)) |
|
40 |
|
41 fun mk_constr T (m, dts) ctxt = |
|
42 let |
|
43 val Ts = map typ_of dts |
|
44 val constr = Const (m, Ts ---> T) |
|
45 val (selects, ctxt') = mk_selectors T Ts ctxt |
|
46 in ((constr, selects), ctxt') end |
|
47 |
|
48 fun mk_decl (i, (_, _, constrs)) ctxt = |
|
49 let |
|
50 val T = typ_of (Datatype.DtRec i) |
|
51 val (css, ctxt') = fold_map (mk_constr T) constrs ctxt |
|
52 in ((T, css), ctxt') end |
|
53 |
|
54 in fold_map mk_decl descr ctxt end |
|
55 |
|
56 |
|
57 (* record declarations *) |
|
58 |
|
59 val record_name_of = Long_Name.implode o fst o split_last o Long_Name.explode |
|
60 |
|
61 fun get_record_decl ({ext_def, ...} : Record.info) T ctxt = |
|
62 let |
|
63 val (con, _) = Term.dest_Const (lhs_head_of ext_def) |
|
64 val (fields, more) = Record.get_extT_fields (Proof_Context.theory_of ctxt) T |
|
65 val fieldTs = map snd fields @ [snd more] |
|
66 |
|
67 val constr = Const (con, fieldTs ---> T) |
|
68 val (selects, ctxt') = mk_selectors T fieldTs ctxt |
|
69 in ((T, [(constr, selects)]), ctxt') end |
|
70 |
37 |
71 |
38 |
72 (* typedef declarations *) |
39 (* typedef declarations *) |
73 |
40 |
74 fun get_typedef_decl (({Abs_name, Rep_name, abs_type, rep_type, ...}, {Abs_inverse, ...}) |
41 fun get_typedef_decl (({Abs_name, Rep_name, abs_type, rep_type, ...}, {Abs_inverse, ...}) |
89 |
56 |
90 fun declared declss T = exists (exists (equal T o fst)) declss |
57 fun declared declss T = exists (exists (equal T o fst)) declss |
91 fun declared' dss T = exists (exists (equal T o fst) o snd) dss |
58 fun declared' dss T = exists (exists (equal T o fst) o snd) dss |
92 |
59 |
93 fun get_decls T n Ts ctxt = |
60 fun get_decls T n Ts ctxt = |
94 let val thy = Proof_Context.theory_of ctxt |
61 (case Ctr_Sugar.ctr_sugar_of ctxt n of |
95 in |
62 SOME ctr_sugar => get_ctr_sugar_decl ctr_sugar T Ts ctxt |
96 (case Datatype.get_info thy n of |
63 | NONE => |
97 SOME info => get_datatype_decl info n Ts ctxt |
64 (case Typedef.get_info ctxt n of |
98 | NONE => |
65 [] => ([], ctxt) |
99 (case Record.get_info thy (record_name_of n) of |
66 | info :: _ => (get_typedef_decl info T Ts, ctxt))) |
100 SOME info => get_record_decl info T ctxt |>> single |
|
101 | NONE => |
|
102 (case Typedef.get_info ctxt n of |
|
103 [] => ([], ctxt) |
|
104 | info :: _ => (get_typedef_decl info T Ts, ctxt)))) |
|
105 end |
|
106 |
67 |
107 fun add_decls T (declss, ctxt) = |
68 fun add_decls T (declss, ctxt) = |
108 let |
69 let |
109 fun depends Ts ds = exists (member (op =) (map fst ds)) Ts |
70 fun depends Ts ds = exists (member (op =) (map fst ds)) Ts |
110 |
71 |