src/HOL/Tools/inductive.ML
changeset 42381 309ec68442c6
parent 42364 8c674b3b8e44
child 42439 9efdd0af15ac
equal deleted inserted replaced
42380:9371ea9f91fb 42381:309ec68442c6
   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