src/HOL/Tools/datatype_package.ML
changeset 8279 3453f73fad71
parent 8100 6186ee807f2e
child 8306 9855f1801d2b
equal deleted inserted replaced
8278:5928c72b7057 8279:3453f73fad71
     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)