267 (** process rules **) |
267 (** process rules **) |
268 |
268 |
269 local |
269 local |
270 |
270 |
271 fun err_in_rule ctxt name t msg = |
271 fun err_in_rule ctxt name t msg = |
272 error (cat_lines ["Ill-formed introduction rule " ^ quote name, |
272 error (cat_lines ["Ill-formed introduction rule " ^ Binding.print name, |
273 Syntax.string_of_term ctxt t, msg]); |
273 Syntax.string_of_term ctxt t, msg]); |
274 |
274 |
275 fun err_in_prem ctxt name t p msg = |
275 fun err_in_prem ctxt name t p msg = |
276 error (cat_lines ["Ill-formed premise", Syntax.string_of_term ctxt p, |
276 error (cat_lines ["Ill-formed premise", Syntax.string_of_term ctxt p, |
277 "in introduction rule " ^ quote name, Syntax.string_of_term ctxt t, msg]); |
277 "in introduction rule " ^ Binding.print name, Syntax.string_of_term ctxt t, msg]); |
278 |
278 |
279 val bad_concl = "Conclusion of introduction rule must be an inductive predicate"; |
279 val bad_concl = "Conclusion of introduction rule must be an inductive predicate"; |
280 |
280 |
281 val bad_ind_occ = "Inductive predicate occurs in argument of inductive predicate"; |
281 val bad_ind_occ = "Inductive predicate occurs in argument of inductive predicate"; |
282 |
282 |
286 |
286 |
287 in |
287 in |
288 |
288 |
289 fun check_rule ctxt cs params ((binding, att), rule) = |
289 fun check_rule ctxt cs params ((binding, att), rule) = |
290 let |
290 let |
291 val err_name = Binding.str_of binding; |
|
292 val params' = Term.variant_frees rule (Logic.strip_params rule); |
291 val params' = Term.variant_frees rule (Logic.strip_params rule); |
293 val frees = rev (map Free params'); |
292 val frees = rev (map Free params'); |
294 val concl = subst_bounds (frees, Logic.strip_assums_concl rule); |
293 val concl = subst_bounds (frees, Logic.strip_assums_concl rule); |
295 val prems = map (curry subst_bounds frees) (Logic.strip_assums_hyp rule); |
294 val prems = map (curry subst_bounds frees) (Logic.strip_assums_hyp rule); |
296 val rule' = Logic.list_implies (prems, concl); |
295 val rule' = Logic.list_implies (prems, concl); |
304 if exists (fn c => exists (fn t => Logic.occs (c, t)) ys) cs |
303 if exists (fn c => exists (fn t => Logic.occs (c, t)) ys) cs |
305 then err bad_ind_occ else (); |
304 then err bad_ind_occ else (); |
306 |
305 |
307 fun check_prem' prem t = |
306 fun check_prem' prem t = |
308 if member (op =) cs (head_of t) then |
307 if member (op =) cs (head_of t) then |
309 check_ind (err_in_prem ctxt err_name rule prem) t |
308 check_ind (err_in_prem ctxt binding rule prem) t |
310 else (case t of |
309 else (case t of |
311 Abs (_, _, t) => check_prem' prem t |
310 Abs (_, _, t) => check_prem' prem t |
312 | t $ u => (check_prem' prem t; check_prem' prem u) |
311 | t $ u => (check_prem' prem t; check_prem' prem u) |
313 | _ => ()); |
312 | _ => ()); |
314 |
313 |
315 fun check_prem (prem, aprem) = |
314 fun check_prem (prem, aprem) = |
316 if can HOLogic.dest_Trueprop aprem then check_prem' prem prem |
315 if can HOLogic.dest_Trueprop aprem then check_prem' prem prem |
317 else err_in_prem ctxt err_name rule prem "Non-atomic premise"; |
316 else err_in_prem ctxt binding rule prem "Non-atomic premise"; |
318 in |
317 in |
319 (case concl of |
318 (case concl of |
320 Const (@{const_name Trueprop}, _) $ t => |
319 Const (@{const_name Trueprop}, _) $ t => |
321 if member (op =) cs (head_of t) then |
320 if member (op =) cs (head_of t) then |
322 (check_ind (err_in_rule ctxt err_name rule') t; |
321 (check_ind (err_in_rule ctxt binding rule') t; |
323 List.app check_prem (prems ~~ aprems)) |
322 List.app check_prem (prems ~~ aprems)) |
324 else err_in_rule ctxt err_name rule' bad_concl |
323 else err_in_rule ctxt binding rule' bad_concl |
325 | _ => err_in_rule ctxt err_name rule' bad_concl); |
324 | _ => err_in_rule ctxt binding rule' bad_concl); |
326 ((binding, att), arule) |
325 ((binding, att), arule) |
327 end; |
326 end; |
328 |
327 |
329 val rulify = |
328 val rulify = |
330 hol_simplify inductive_conj |
329 hol_simplify inductive_conj |