src/Pure/Isar/code.ML
changeset 51685 385ef6706252
parent 51584 98029ceda8ce
child 51717 9e7d1c139569
equal deleted inserted replaced
51671:0d142a78fb7c 51685:385ef6706252
   105 fun string_of_typ thy =
   105 fun string_of_typ thy =
   106   Syntax.string_of_typ (Config.put show_sorts true (Syntax.init_pretty_global thy));
   106   Syntax.string_of_typ (Config.put show_sorts true (Syntax.init_pretty_global thy));
   107 
   107 
   108 fun string_of_const thy c =
   108 fun string_of_const thy c =
   109   let val ctxt = Proof_Context.init_global thy in
   109   let val ctxt = Proof_Context.init_global thy in
   110     case AxClass.inst_of_param thy c of
   110     case Axclass.inst_of_param thy c of
   111       SOME (c, tyco) =>
   111       SOME (c, tyco) =>
   112         Proof_Context.extern_const ctxt c ^ " " ^ enclose "[" "]"
   112         Proof_Context.extern_const ctxt c ^ " " ^ enclose "[" "]"
   113           (Proof_Context.extern_type ctxt tyco)
   113           (Proof_Context.extern_type ctxt tyco)
   114     | NONE => Proof_Context.extern_const ctxt c
   114     | NONE => Proof_Context.extern_const ctxt c
   115   end;
   115   end;
   138  of SOME c_ty => c_ty
   138  of SOME c_ty => c_ty
   139   | NONE => error ("Not a constant: " ^ Syntax.string_of_term_global thy t);
   139   | NONE => error ("Not a constant: " ^ Syntax.string_of_term_global thy t);
   140 
   140 
   141 fun check_unoverload thy (c, ty) =
   141 fun check_unoverload thy (c, ty) =
   142   let
   142   let
   143     val c' = AxClass.unoverload_const thy (c, ty);
   143     val c' = Axclass.unoverload_const thy (c, ty);
   144     val ty_decl = Sign.the_const_type thy c';
   144     val ty_decl = Sign.the_const_type thy c';
   145   in
   145   in
   146     if typscheme_equiv (ty_decl, Logic.varifyT_global ty)
   146     if typscheme_equiv (ty_decl, Logic.varifyT_global ty)
   147     then c'
   147     then c'
   148     else
   148     else
   373     val (_, vs) = last_typ (c, ty) ty;
   373     val (_, vs) = last_typ (c, ty) ty;
   374   in ((tyco, map snd vs), (c, (map fst vs, ty))) end;
   374   in ((tyco, map snd vs), (c, (map fst vs, ty))) end;
   375 
   375 
   376 fun constrset_of_consts thy consts =
   376 fun constrset_of_consts thy consts =
   377   let
   377   let
   378     val _ = map (fn (c, _) => if (is_some o AxClass.class_of_param thy) c
   378     val _ = map (fn (c, _) => if (is_some o Axclass.class_of_param thy) c
   379       then error ("Is a class parameter: " ^ string_of_const thy c) else ()) consts;
   379       then error ("Is a class parameter: " ^ string_of_const thy c) else ()) consts;
   380     val raw_constructors = map (analyze_constructor thy) consts;
   380     val raw_constructors = map (analyze_constructor thy) consts;
   381     val tyco = case distinct (op =) (map (fst o fst) raw_constructors)
   381     val tyco = case distinct (op =) (map (fst o fst) raw_constructors)
   382      of [tyco] => tyco
   382      of [tyco] => tyco
   383       | [] => error "Empty constructor set"
   383       | [] => error "Empty constructor set"
   475     val _ = if null (subtract (op =) lhs_tvs rhs_tvs)
   475     val _ = if null (subtract (op =) lhs_tvs rhs_tvs)
   476       then ()
   476       then ()
   477       else bad_thm "Free type variables on right hand side of equation";
   477       else bad_thm "Free type variables on right hand side of equation";
   478     val (head, args) = strip_comb lhs;
   478     val (head, args) = strip_comb lhs;
   479     val (c, ty) = case head
   479     val (c, ty) = case head
   480      of Const (c_ty as (_, ty)) => (AxClass.unoverload_const thy c_ty, ty)
   480      of Const (c_ty as (_, ty)) => (Axclass.unoverload_const thy c_ty, ty)
   481       | _ => bad_thm "Equation not headed by constant";
   481       | _ => bad_thm "Equation not headed by constant";
   482     fun check _ (Abs _) = bad_thm "Abstraction on left hand side of equation"
   482     fun check _ (Abs _) = bad_thm "Abstraction on left hand side of equation"
   483       | check 0 (Var _) = ()
   483       | check 0 (Var _) = ()
   484       | check _ (Var _) = bad_thm "Variable with application on left hand side of equation"
   484       | check _ (Var _) = bad_thm "Variable with application on left hand side of equation"
   485       | check n (t1 $ t2) = (check (n+1) t1; check 0 t2)
   485       | check n (t1 $ t2) = (check (n+1) t1; check 0 t2)
   486       | check n (Const (c_ty as (c, ty))) =
   486       | check n (Const (c_ty as (c, ty))) =
   487           if allow_pats then let
   487           if allow_pats then let
   488             val c' = AxClass.unoverload_const thy c_ty
   488             val c' = Axclass.unoverload_const thy c_ty
   489           in if n = (length o binder_types) ty
   489           in if n = (length o binder_types) ty
   490             then if allow_consts orelse is_constr thy c'
   490             then if allow_consts orelse is_constr thy c'
   491               then ()
   491               then ()
   492               else bad_thm (quote c ^ " is not a constructor, on left hand side of equation")
   492               else bad_thm (quote c ^ " is not a constructor, on left hand side of equation")
   493             else bad_thm ("Partially applied constant " ^ quote c ^ " on left hand side of equation")
   493             else bad_thm ("Partially applied constant " ^ quote c ^ " on left hand side of equation")
   494           end else bad_thm ("Pattern not allowed here, but constant " ^ quote c ^ " encountered on left hand side of equation")
   494           end else bad_thm ("Pattern not allowed here, but constant " ^ quote c ^ " encountered on left hand side of equation")
   495     val _ = map (check 0) args;
   495     val _ = map (check 0) args;
   496     val _ = if allow_nonlinear orelse is_linear thm then ()
   496     val _ = if allow_nonlinear orelse is_linear thm then ()
   497       else bad_thm "Duplicate variables on left hand side of equation";
   497       else bad_thm "Duplicate variables on left hand side of equation";
   498     val _ = if (is_none o AxClass.class_of_param thy) c then ()
   498     val _ = if (is_none o Axclass.class_of_param thy) c then ()
   499       else bad_thm "Overloaded constant as head in equation";
   499       else bad_thm "Overloaded constant as head in equation";
   500     val _ = if not (is_constr thy c) then ()
   500     val _ = if not (is_constr thy c) then ()
   501       else bad_thm "Constructor as head in equation";
   501       else bad_thm "Constructor as head in equation";
   502     val _ = if not (is_abstr thy c) then ()
   502     val _ = if not (is_abstr thy c) then ()
   503       else bad_thm "Abstractor as head in equation";
   503       else bad_thm "Abstractor as head in equation";
   555 val head_eqn = dest_Const o fst o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
   555 val head_eqn = dest_Const o fst o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
   556 
   556 
   557 fun const_typ_eqn thy thm =
   557 fun const_typ_eqn thy thm =
   558   let
   558   let
   559     val (c, ty) = head_eqn thm;
   559     val (c, ty) = head_eqn thm;
   560     val c' = AxClass.unoverload_const thy (c, ty);
   560     val c' = Axclass.unoverload_const thy (c, ty);
   561       (*permissive wrt. to overloaded constants!*)
   561       (*permissive wrt. to overloaded constants!*)
   562   in (c', ty) end;
   562   in (c', ty) end;
   563 
   563 
   564 fun const_eqn thy = fst o const_typ_eqn thy;
   564 fun const_eqn thy = fst o const_typ_eqn thy;
   565 
   565 
   566 fun const_abs_eqn thy = AxClass.unoverload_const thy o dest_Const o fst o strip_comb o snd
   566 fun const_abs_eqn thy = Axclass.unoverload_const thy o dest_Const o fst o strip_comb o snd
   567   o dest_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
   567   o dest_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
   568 
   568 
   569 fun mk_proj tyco vs ty abs rep =
   569 fun mk_proj tyco vs ty abs rep =
   570   let
   570   let
   571     val ty_abs = Type (tyco, map TFree vs);
   571     val ty_abs = Type (tyco, map TFree vs);
   627 
   627 
   628 (* abstype certificates *)
   628 (* abstype certificates *)
   629 
   629 
   630 fun check_abstype_cert thy proto_thm =
   630 fun check_abstype_cert thy proto_thm =
   631   let
   631   let
   632     val thm = (AxClass.unoverload thy o meta_rewrite thy) proto_thm;
   632     val thm = (Axclass.unoverload thy o meta_rewrite thy) proto_thm;
   633     val (lhs, rhs) = Logic.dest_equals (Thm.plain_prop_of thm)
   633     val (lhs, rhs) = Logic.dest_equals (Thm.plain_prop_of thm)
   634       handle TERM _ => bad_thm "Not an equation"
   634       handle TERM _ => bad_thm "Not an equation"
   635            | THM _ => bad_thm "Not a proper equation";
   635            | THM _ => bad_thm "Not a proper equation";
   636     val ((abs, raw_ty), ((rep, rep_ty), param)) = (apsnd (apfst dest_Const o dest_comb)
   636     val ((abs, raw_ty), ((rep, rep_ty), param)) = (apsnd (apfst dest_Const o dest_comb)
   637         o apfst dest_Const o dest_comb) lhs
   637         o apfst dest_Const o dest_comb) lhs
   638       handle TERM _ => bad_thm "Not an abstype certificate";
   638       handle TERM _ => bad_thm "Not an abstype certificate";
   639     val _ = pairself (fn c => if (is_some o AxClass.class_of_param thy) c
   639     val _ = pairself (fn c => if (is_some o Axclass.class_of_param thy) c
   640       then error ("Is a class parameter: " ^ string_of_const thy c) else ()) (abs, rep);
   640       then error ("Is a class parameter: " ^ string_of_const thy c) else ()) (abs, rep);
   641     val _ = check_decl_ty thy (abs, raw_ty);
   641     val _ = check_decl_ty thy (abs, raw_ty);
   642     val _ = check_decl_ty thy (rep, rep_ty);
   642     val _ = check_decl_ty thy (rep, rep_ty);
   643     val _ = if length (binder_types raw_ty) = 1
   643     val _ = if length (binder_types raw_ty) = 1
   644       then ()
   644       then ()
   712 
   712 
   713 fun empty_cert thy c = 
   713 fun empty_cert thy c = 
   714   let
   714   let
   715     val raw_ty = Logic.unvarifyT_global (const_typ thy c);
   715     val raw_ty = Logic.unvarifyT_global (const_typ thy c);
   716     val (vs, _) = typscheme thy (c, raw_ty);
   716     val (vs, _) = typscheme thy (c, raw_ty);
   717     val sortargs = case AxClass.class_of_param thy c
   717     val sortargs = case Axclass.class_of_param thy c
   718      of SOME class => [[class]]
   718      of SOME class => [[class]]
   719       | NONE => (case get_type_of_constr_or_abstr thy c
   719       | NONE => (case get_type_of_constr_or_abstr thy c
   720          of SOME (tyco, _) => (map snd o fst o the)
   720          of SOME (tyco, _) => (map snd o fst o the)
   721               (AList.lookup (op =) ((snd o fst o get_type thy) tyco) c)
   721               (AList.lookup (op =) ((snd o fst o get_type thy) tyco) c)
   722           | NONE => replicate (length vs) []);
   722           | NONE => replicate (length vs) []);
   838         (tyscm, [((abstractions o dest_eqn o Thm.prop_of) concrete_thm,
   838         (tyscm, [((abstractions o dest_eqn o Thm.prop_of) concrete_thm,
   839           (SOME (Thm.varifyT_global abs_thm), true))])
   839           (SOME (Thm.varifyT_global abs_thm), true))])
   840       end;
   840       end;
   841 
   841 
   842 fun pretty_cert thy (cert as Equations _) =
   842 fun pretty_cert thy (cert as Equations _) =
   843       (map_filter (Option.map (Display.pretty_thm_global thy o AxClass.overload thy) o fst o snd)
   843       (map_filter (Option.map (Display.pretty_thm_global thy o Axclass.overload thy) o fst o snd)
   844          o snd o equations_of_cert thy) cert
   844          o snd o equations_of_cert thy) cert
   845   | pretty_cert thy (Projection (t, _)) =
   845   | pretty_cert thy (Projection (t, _)) =
   846       [Syntax.pretty_term_global thy (Logic.varify_types_global t)]
   846       [Syntax.pretty_term_global thy (Logic.varify_types_global t)]
   847   | pretty_cert thy (Abstract (abs_thm, _)) =
   847   | pretty_cert thy (Abstract (abs_thm, _)) =
   848       [(Display.pretty_thm_global thy o AxClass.overload thy o Thm.varifyT_global) abs_thm];
   848       [(Display.pretty_thm_global thy o Axclass.overload thy o Thm.varifyT_global) abs_thm];
   849 
   849 
   850 fun bare_thms_of_cert thy (cert as Equations _) =
   850 fun bare_thms_of_cert thy (cert as Equations _) =
   851       (map_filter (fn (_, (some_thm, proper)) => if proper then some_thm else NONE)
   851       (map_filter (fn (_, (some_thm, proper)) => if proper then some_thm else NONE)
   852         o snd o equations_of_cert thy) cert
   852         o snd o equations_of_cert thy) cert
   853   | bare_thms_of_cert thy (Projection _) = []
   853   | bare_thms_of_cert thy (Projection _) = []
   879 
   879 
   880 fun cert_of_eqns_preprocess thy functrans ss c =
   880 fun cert_of_eqns_preprocess thy functrans ss c =
   881   (map o apfst) (Thm.transfer thy)
   881   (map o apfst) (Thm.transfer thy)
   882   #> perhaps (perhaps_loop (perhaps_apply functrans))
   882   #> perhaps (perhaps_loop (perhaps_apply functrans))
   883   #> (map o apfst) (rewrite_eqn thy eqn_conv ss) 
   883   #> (map o apfst) (rewrite_eqn thy eqn_conv ss) 
   884   #> (map o apfst) (AxClass.unoverload thy)
   884   #> (map o apfst) (Axclass.unoverload thy)
   885   #> cert_of_eqns thy c;
   885   #> cert_of_eqns thy c;
   886 
   886 
   887 fun get_cert thy { functrans, ss } c =
   887 fun get_cert thy { functrans, ss } c =
   888   case retrieve_raw thy c
   888   case retrieve_raw thy c
   889    of Default (_, eqns_lazy) => Lazy.force eqns_lazy
   889    of Default (_, eqns_lazy) => Lazy.force eqns_lazy
   893     | Proj (_, tyco) =>
   893     | Proj (_, tyco) =>
   894         cert_of_proj thy c tyco
   894         cert_of_proj thy c tyco
   895     | Abstr (abs_thm, tyco) => abs_thm
   895     | Abstr (abs_thm, tyco) => abs_thm
   896         |> Thm.transfer thy
   896         |> Thm.transfer thy
   897         |> rewrite_eqn thy Conv.arg_conv ss
   897         |> rewrite_eqn thy Conv.arg_conv ss
   898         |> AxClass.unoverload thy
   898         |> Axclass.unoverload thy
   899         |> cert_of_abs thy tyco c;
   899         |> cert_of_abs thy tyco c;
   900 
   900 
   901 
   901 
   902 (* cases *)
   902 (* cases *)
   903 
   903 
  1170     |> map_exec_purge
  1170     |> map_exec_purge
  1171         ((map_typs o Symtab.map_default (tyco, [])) (cons (serial (), vs_spec))
  1171         ((map_typs o Symtab.map_default (tyco, [])) (cons (serial (), vs_spec))
  1172         #> (map_cases o apfst) drop_outdated_cases)
  1172         #> (map_cases o apfst) drop_outdated_cases)
  1173   end;
  1173   end;
  1174 
  1174 
  1175 fun unoverload_const_typ thy (c, ty) = (AxClass.unoverload_const thy (c, ty), ty);
  1175 fun unoverload_const_typ thy (c, ty) = (Axclass.unoverload_const thy (c, ty), ty);
  1176 
  1176 
  1177 structure Datatype_Interpretation =
  1177 structure Datatype_Interpretation =
  1178   Interpretation(type T = string * serial val eq = eq_snd (op =) : T * T -> bool);
  1178   Interpretation(type T = string * serial val eq = eq_snd (op =) : T * T -> bool);
  1179 
  1179 
  1180 fun datatype_interpretation f = Datatype_Interpretation.interpretation
  1180 fun datatype_interpretation f = Datatype_Interpretation.interpretation