8 |
8 |
9 signature BASIC_DATATYPE_PACKAGE = |
9 signature BASIC_DATATYPE_PACKAGE = |
10 sig |
10 sig |
11 val induct_tac : string -> int -> tactic |
11 val induct_tac : string -> int -> tactic |
12 val exhaust_tac : string -> int -> tactic |
12 val exhaust_tac : string -> int -> tactic |
|
13 val cases_tac : string -> int -> tactic |
13 val distinct_simproc : simproc |
14 val distinct_simproc : simproc |
14 end; |
15 end; |
15 |
16 |
16 signature DATATYPE_PACKAGE = |
17 signature DATATYPE_PACKAGE = |
17 sig |
18 sig |
68 val datatype_info_sg_err : Sign.sg -> string -> DatatypeAux.datatype_info |
69 val datatype_info_sg_err : Sign.sg -> string -> DatatypeAux.datatype_info |
69 val datatype_info_err : theory -> string -> DatatypeAux.datatype_info |
70 val datatype_info_err : theory -> string -> DatatypeAux.datatype_info |
70 val constrs_of : theory -> string -> term list option |
71 val constrs_of : theory -> string -> term list option |
71 val constrs_of_sg : Sign.sg -> string -> term list option |
72 val constrs_of_sg : Sign.sg -> string -> term list option |
72 val case_const_of : theory -> string -> term option |
73 val case_const_of : theory -> string -> term option |
|
74 val cases_of: Sign.sg -> string -> thm |
73 val setup: (theory -> theory) list |
75 val setup: (theory -> theory) list |
74 end; |
76 end; |
75 |
77 |
76 structure DatatypePackage : DATATYPE_PACKAGE = |
78 structure DatatypePackage : DATATYPE_PACKAGE = |
77 struct |
79 struct |
125 in Some (map (fn (cname, _) => Const (cname, the (Sign.const_type sg cname))) constrs) |
127 in Some (map (fn (cname, _) => Const (cname, the (Sign.const_type sg cname))) constrs) |
126 end |
128 end |
127 | _ => None); |
129 | _ => None); |
128 |
130 |
129 val constrs_of = constrs_of_sg o Theory.sign_of; |
131 val constrs_of = constrs_of_sg o Theory.sign_of; |
|
132 |
|
133 val exhaustion_of = #exhaustion oo datatype_info_sg_err |
|
134 fun cases_of sg name = if name = HOLogic.boolN then case_split_thm else exhaustion_of sg name; |
130 |
135 |
131 fun case_const_of thy tname = (case datatype_info thy tname of |
136 fun case_const_of thy tname = (case datatype_info thy tname of |
132 Some {case_name, ...} => Some (Const (case_name, the (Sign.const_type |
137 Some {case_name, ...} => Some (Const (case_name, the (Sign.const_type |
133 (Theory.sign_of thy) case_name))) |
138 (Theory.sign_of thy) case_name))) |
134 | _ => None); |
139 | _ => None); |
140 None => error ("No such variable in subgoal: " ^ quote var) |
145 None => error ("No such variable in subgoal: " ^ quote var) |
141 | Some(Type (tn, _)) => tn |
146 | Some(Type (tn, _)) => tn |
142 | _ => error ("Cannot determine type of " ^ quote var) |
147 | _ => error ("Cannot determine type of " ^ quote var) |
143 end; |
148 end; |
144 |
149 |
145 fun infer_tname state sign i aterm = |
150 fun infer_tname state i aterm = |
146 let |
151 let |
147 val (_, _, Bi, _) = dest_state (state, i) |
152 val sign = Thm.sign_of_thm state; |
|
153 val (_, _, Bi, _) = Thm.dest_state (state, i) |
148 val params = Logic.strip_params Bi; (*params of subgoal i*) |
154 val params = Logic.strip_params Bi; (*params of subgoal i*) |
149 val params = rev (rename_wrt_term Bi params); (*as they are printed*) |
155 val params = rev (rename_wrt_term Bi params); (*as they are printed*) |
150 val (types, sorts) = types_sorts state; |
156 val (types, sorts) = types_sorts state; |
151 fun types' (a, ~1) = (case assoc (params, a) of None => types(a, ~1) | sm => sm) |
157 fun types' (a, ~1) = (case assoc (params, a) of None => types(a, ~1) | sm => sm) |
152 | types' ixn = types ixn; |
158 | types' ixn = types ixn; |
182 error ("Induction rule for type " ^ tn ^ " has different number of variables") |
188 error ("Induction rule for type " ^ tn ^ " has different number of variables") |
183 in |
189 in |
184 occs_in_prems (res_inst_tac insts induction) vars i state |
190 occs_in_prems (res_inst_tac insts induction) vars i state |
185 end; |
191 end; |
186 |
192 |
|
193 |
187 (* generic exhaustion tactic for datatypes *) |
194 (* generic exhaustion tactic for datatypes *) |
188 |
195 |
189 fun exhaust_tac aterm i state = |
196 fun gen_exhaust_tac get_rule aterm i state = |
190 let |
197 let |
191 val {sign, ...} = rep_thm state; |
198 val rule = get_rule (Thm.sign_of_thm state) (infer_tname state i aterm); |
192 val tn = infer_tname state sign i aterm; |
|
193 val {exhaustion, ...} = datatype_info_sg_err sign tn; |
|
194 val _ $ Var (ixn, _) $ _ = HOLogic.dest_Trueprop |
199 val _ $ Var (ixn, _) $ _ = HOLogic.dest_Trueprop |
195 (hd (Logic.strip_assums_hyp (hd (prems_of exhaustion)))); |
200 (hd (Logic.strip_assums_hyp (hd (Thm.prems_of rule)))); |
196 val exh_vname = implode (tl (explode (Syntax.string_of_vname ixn))) |
201 val exh_vname = implode (tl (explode (Syntax.string_of_vname ixn))) |
197 in |
202 in res_inst_tac [(exh_vname, aterm)] rule i state end; |
198 res_inst_tac [(exh_vname, aterm)] exhaustion i state |
203 |
199 end; |
204 val exhaust_tac = gen_exhaust_tac exhaustion_of; |
|
205 val cases_tac = gen_exhaust_tac cases_of; |
|
206 |
200 |
207 |
201 |
208 |
202 (**** simplification procedure for showing distinctness of constructors ****) |
209 (**** simplification procedure for showing distinctness of constructors ****) |
203 |
210 |
204 fun stripT (i, Type ("fun", [_, T])) = stripT (i + 1, T) |
211 fun stripT (i, Type ("fun", [_, T])) = stripT (i + 1, T) |