src/Tools/induct.ML
changeset 58826 2ed2eaabe3df
parent 58002 0ed1e999a0fb
child 58838 59203adfc33f
equal deleted inserted replaced
58825:2065f49da190 58826:2ed2eaabe3df
    87   val gen_induct_setup: binding ->
    87   val gen_induct_setup: binding ->
    88    (Proof.context -> bool -> (binding option * (term * bool)) option list list ->
    88    (Proof.context -> bool -> (binding option * (term * bool)) option list list ->
    89     (string * typ) list list -> term option list -> thm list option ->
    89     (string * typ) list list -> term option list -> thm list option ->
    90     thm list -> int -> cases_tactic) ->
    90     thm list -> int -> cases_tactic) ->
    91    theory -> theory
    91    theory -> theory
    92   val setup: theory -> theory
       
    93 end;
    92 end;
    94 
    93 
    95 functor Induct(Induct_Args: INDUCT_ARGS): INDUCT =
    94 functor Induct(Induct_Args: INDUCT_ARGS): INDUCT =
    96 struct
    95 struct
    97 
    96 
   366   spec setN (Args.const {proper = false, strict = false}) >> add_pred ||
   365   spec setN (Args.const {proper = false, strict = false}) >> add_pred ||
   367   Scan.lift Args.del >> K del;
   366   Scan.lift Args.del >> K del;
   368 
   367 
   369 in
   368 in
   370 
   369 
   371 val attrib_setup =
   370 val _ =
   372   Attrib.setup @{binding cases} (attrib cases_type cases_pred cases_del)
   371   Theory.setup
   373     "declaration of cases rule" #>
   372    (Attrib.setup @{binding cases} (attrib cases_type cases_pred cases_del)
   374   Attrib.setup @{binding induct} (attrib induct_type induct_pred induct_del)
   373       "declaration of cases rule" #>
   375     "declaration of induction rule" #>
   374     Attrib.setup @{binding induct} (attrib induct_type induct_pred induct_del)
   376   Attrib.setup @{binding coinduct} (attrib coinduct_type coinduct_pred coinduct_del)
   375       "declaration of induction rule" #>
   377     "declaration of coinduction rule" #>
   376     Attrib.setup @{binding coinduct} (attrib coinduct_type coinduct_pred coinduct_del)
   378   Attrib.setup @{binding induct_simp} (Attrib.add_del induct_simp_add induct_simp_del)
   377       "declaration of coinduction rule" #>
   379     "declaration of rules for simplifying induction or cases rules";
   378     Attrib.setup @{binding induct_simp} (Attrib.add_del induct_simp_add induct_simp_del)
       
   379       "declaration of rules for simplifying induction or cases rules");
   380 
   380 
   381 end;
   381 end;
   382 
   382 
   383 
   383 
   384 
   384 
   921 val taking = Scan.optional (Scan.lift (Args.$$$ takingN -- Args.colon) |--
   921 val taking = Scan.optional (Scan.lift (Args.$$$ takingN -- Args.colon) |--
   922   Scan.repeat1 (unless_more_args inst)) [];
   922   Scan.repeat1 (unless_more_args inst)) [];
   923 
   923 
   924 in
   924 in
   925 
   925 
   926 val cases_setup =
   926 val _ =
   927   Method.setup @{binding cases}
   927   Theory.setup
   928     (Scan.lift (Args.mode no_simpN) --
   928     (Method.setup @{binding cases}
   929       (Parse.and_list' (Scan.repeat (unless_more_args inst)) -- Scan.option cases_rule) >>
   929       (Scan.lift (Args.mode no_simpN) --
   930       (fn (no_simp, (insts, opt_rule)) => fn ctxt =>
   930         (Parse.and_list' (Scan.repeat (unless_more_args inst)) -- Scan.option cases_rule) >>
   931         METHOD_CASES (fn facts => Seq.DETERM (HEADGOAL
   931         (fn (no_simp, (insts, opt_rule)) => fn ctxt =>
   932           (cases_tac ctxt (not no_simp) insts opt_rule facts)))))
   932           METHOD_CASES (fn facts => Seq.DETERM (HEADGOAL
   933     "case analysis on types or predicates/sets";
   933             (cases_tac ctxt (not no_simp) insts opt_rule facts)))))
       
   934       "case analysis on types or predicates/sets");
   934 
   935 
   935 fun gen_induct_setup binding tac =
   936 fun gen_induct_setup binding tac =
   936   Method.setup binding
   937   Method.setup binding
   937     (Scan.lift (Args.mode no_simpN) --
   938     (Scan.lift (Args.mode no_simpN) --
   938       (Parse.and_list' (Scan.repeat (unless_more_args def_inst)) --
   939       (Parse.and_list' (Scan.repeat (unless_more_args def_inst)) --
   939         (arbitrary -- taking -- Scan.option induct_rule)) >>
   940         (arbitrary -- taking -- Scan.option induct_rule)) >>
   940       (fn (no_simp, (insts, ((arbitrary, taking), opt_rule))) => fn ctxt => fn facts =>
   941       (fn (no_simp, (insts, ((arbitrary, taking), opt_rule))) => fn ctxt => fn facts =>
   941         Seq.DETERM (HEADGOAL (tac ctxt (not no_simp) insts arbitrary taking opt_rule facts))))
   942         Seq.DETERM (HEADGOAL (tac ctxt (not no_simp) insts arbitrary taking opt_rule facts))))
   942     "induction on types or predicates/sets";
   943     "induction on types or predicates/sets";
   943 
   944 
   944 val induct_setup = gen_induct_setup @{binding induct} induct_tac;
   945 val _ = Theory.setup (gen_induct_setup @{binding induct} induct_tac);
   945 
   946 
   946 val coinduct_setup =
   947 val _ =
   947   Method.setup @{binding coinduct}
   948   Theory.setup
   948     (Scan.repeat (unless_more_args inst) -- taking -- Scan.option coinduct_rule >>
   949     (Method.setup @{binding coinduct}
   949       (fn ((insts, taking), opt_rule) => fn ctxt => fn facts =>
   950       (Scan.repeat (unless_more_args inst) -- taking -- Scan.option coinduct_rule >>
   950         Seq.DETERM (HEADGOAL (coinduct_tac ctxt insts taking opt_rule facts))))
   951         (fn ((insts, taking), opt_rule) => fn ctxt => fn facts =>
   951     "coinduction on types or predicates/sets";
   952           Seq.DETERM (HEADGOAL (coinduct_tac ctxt insts taking opt_rule facts))))
   952 
   953       "coinduction on types or predicates/sets");
   953 end;
   954 
   954 
   955 end;
   955 
   956 
   956 
   957 end;
   957 (** theory setup **)
       
   958 
       
   959 val setup = attrib_setup #> cases_setup  #> induct_setup #> coinduct_setup;
       
   960 
       
   961 end;