20 (** STILL NEEDS: some treatment of recursion **) |
20 (** STILL NEEDS: some treatment of recursion **) |
21 |
21 |
22 signature CONSTRUCTOR = |
22 signature CONSTRUCTOR = |
23 sig |
23 sig |
24 val thy : theory (*parent theory*) |
24 val thy : theory (*parent theory*) |
25 val rec_specs : (string * string * (string list * string)list) list |
25 val rec_specs : (string * string * (string list * string * mixfix)list) list |
26 (*recursion ops, types, domains, constructors*) |
26 (*recursion ops, types, domains, constructors*) |
27 val rec_styp : string (*common type of all recursion ops*) |
27 val rec_styp : string (*common type of all recursion ops*) |
28 val ext : Syntax.sext option (*syntax extension for new theory*) |
|
29 val sintrs : string list (*desired introduction rules*) |
28 val sintrs : string list (*desired introduction rules*) |
30 val monos : thm list (*monotonicity of each M operator*) |
29 val monos : thm list (*monotonicity of each M operator*) |
31 val type_intrs : thm list (*type-checking intro rules*) |
30 val type_intrs : thm list (*type-checking intro rules*) |
32 val type_elims : thm list (*type-checking elim rules*) |
31 val type_elims : thm list (*type-checking elim rules*) |
33 end; |
32 end; |
61 |
60 |
62 val dummy = assert_all Syntax.is_identifier rec_names |
61 val dummy = assert_all Syntax.is_identifier rec_names |
63 (fn a => "Name of recursive set not an identifier: " ^ a); |
62 (fn a => "Name of recursive set not an identifier: " ^ a); |
64 |
63 |
65 (*Expands multiple constant declarations*) |
64 (*Expands multiple constant declarations*) |
66 fun pairtypes (cs,st) = map (rpair st) cs; |
65 fun flatten_consts ((names, typ, mfix) :: cs) = |
|
66 let fun mk_const name = (name, typ, mfix) |
|
67 in (map mk_const names) @ (flatten_consts cs) end |
|
68 | flatten_consts [] = []; |
67 |
69 |
68 (*Constructors with types and arguments*) |
70 (*Constructors with types and arguments*) |
69 fun mk_con_ty_list cons_pairs = |
71 fun mk_con_ty_list cons_pairs = |
70 let fun mk_con_ty (a,st) = |
72 let fun mk_con_ty (a, st, syn) = |
71 let val T = rdty st |
73 let val T = rdty st; |
72 val args = mk_frees "xa" (binder_types T) |
74 val args = mk_frees "xa" (binder_types T); |
73 in (a,T,args) end |
75 val name = const_name a syn; (* adds "op" to infix constructors*) |
74 in map mk_con_ty (flat (map pairtypes cons_pairs)) end; |
76 in (name, T, args) end; |
|
77 |
|
78 fun pairtypes c = flatten_consts [c]; |
|
79 in map mk_con_ty (flat (map pairtypes cons_pairs)) end; |
75 |
80 |
76 val con_ty_lists = map (mk_con_ty_list o #3) rec_specs; |
81 val con_ty_lists = map (mk_con_ty_list o #3) rec_specs; |
77 |
82 |
78 (** Define the constructors **) |
83 (** Define the constructors **) |
79 |
84 |
85 |
90 |
86 val npart = length rec_names; (*number of mutually recursive parts*) |
91 val npart = length rec_names; (*number of mutually recursive parts*) |
87 |
92 |
88 (*Make constructor definition*) |
93 (*Make constructor definition*) |
89 fun mk_con_defs (kpart, con_ty_list) = |
94 fun mk_con_defs (kpart, con_ty_list) = |
90 let val ncon = length con_ty_list (*number of constructors*) |
95 let val ncon = length con_ty_list (*number of constructors*) |
91 fun mk_def ((a,T,args), kcon) = (*kcon = index of this constructor*) |
96 fun mk_def ((a,T,args), kcon) = (*kcon = index of this constructor*) |
92 mk_defpair sign |
97 mk_defpair sign |
93 (list_comb (Const(a,T), args), |
98 (list_comb (Const(a,T), args), |
94 mk_inject npart kpart (mk_inject ncon kcon (mk_tuple args))) |
99 mk_inject npart kpart (mk_inject ncon kcon (mk_tuple args))) |
95 in map mk_def (con_ty_list ~~ (1 upto ncon)) end; |
100 in map mk_def (con_ty_list ~~ (1 upto ncon)) end; |
96 |
101 |
105 (** Generating function variables for the case definition |
110 (** Generating function variables for the case definition |
106 Non-identifiers (e.g. infixes) get a name of the form f_op_nnn. **) |
111 Non-identifiers (e.g. infixes) get a name of the form f_op_nnn. **) |
107 |
112 |
108 (*Treatment of a single constructor*) |
113 (*Treatment of a single constructor*) |
109 fun add_case ((a,T,args), (opno,cases)) = |
114 fun add_case ((a,T,args), (opno,cases)) = |
110 if Syntax.is_identifier a |
115 if Syntax.is_identifier a |
111 then (opno, |
116 then (opno, |
112 (Free(case_name ^ "_" ^ a, T), args) :: cases) |
117 (Free(case_name ^ "_" ^ a, T), args) :: cases) |
113 else (opno+1, |
118 else (opno+1, |
114 (Free(case_name ^ "_op_" ^ string_of_int opno, T), args) :: cases); |
119 (Free(case_name ^ "_op_" ^ string_of_int opno, T), args) :: cases); |
115 |
120 |
140 (** Build the new theory **) |
145 (** Build the new theory **) |
141 |
146 |
142 val axpairs = |
147 val axpairs = |
143 big_case_def :: flat (map mk_con_defs ((1 upto npart) ~~ con_ty_lists)); |
148 big_case_def :: flat (map mk_con_defs ((1 upto npart) ~~ con_ty_lists)); |
144 |
149 |
145 val const_decs = remove_mixfixes ext |
150 val const_decs = flatten_consts |
146 (([big_case_name], flatten_typ sign big_case_typ) :: |
151 (([big_case_name], flatten_typ sign big_case_typ, NoSyn) :: |
147 (big_rec_name ins rec_names, rec_styp) :: |
152 (big_rec_name ins rec_names, rec_styp, NoSyn) :: |
148 flat (map #3 rec_specs)); |
153 flat (map #3 rec_specs)); |
149 |
154 |
150 val con_thy = extend_theory thy (big_rec_name ^ "_Constructors") |
155 val con_thy = thy |
151 ([], [], [], [], [], const_decs, ext) axpairs; |
156 |> add_consts const_decs |
|
157 |> add_axioms axpairs |
|
158 |> add_thyname (big_rec_name ^ "_Constructors"); |
152 |
159 |
153 (*1st element is the case definition; others are the constructors*) |
160 (*1st element is the case definition; others are the constructors*) |
154 val con_defs = map (get_axiom con_thy o #1) axpairs; |
161 val con_defs = map (get_axiom con_thy o #1) axpairs; |
155 |
162 |
156 (** Prove the case theorem **) |
163 (** Prove the case theorem **) |