src/Tools/Code/code_thingol.ML
changeset 77702 b5fbe9837aee
parent 77701 5af3954ed6cf
child 77703 0262155d2743
equal deleted inserted replaced
77701:5af3954ed6cf 77702:b5fbe9837aee
   512 
   512 
   513 fun annotate ctxt algbr eqngr (c, ty) args rhs =
   513 fun annotate ctxt algbr eqngr (c, ty) args rhs =
   514   let
   514   let
   515     val erase = map_types (fn _ => Type_Infer.anyT []);
   515     val erase = map_types (fn _ => Type_Infer.anyT []);
   516     val reinfer = singleton (Type_Infer_Context.infer_types ctxt);
   516     val reinfer = singleton (Type_Infer_Context.infer_types ctxt);
   517     val lhs = list_comb (Const (c, ty), map (map_types Type.strip_sorts o fst) args);
   517     val lhs = list_comb (Const (c, ty), map (map_types Type.strip_sorts o snd) args);
   518     val reinferred_rhs = snd (Logic.dest_equals (reinfer (Logic.mk_equals (lhs, erase rhs))));
   518     val reinferred_rhs = snd (Logic.dest_equals (reinfer (Logic.mk_equals (lhs, erase rhs))));
   519   in tag_term algbr eqngr reinferred_rhs rhs end
   519   in tag_term algbr eqngr reinferred_rhs rhs end
   520 
   520 
   521 fun annotate_eqns ctxt algbr eqngr (c, ty) eqns =
   521 fun annotate_eqns ctxt algbr eqngr (c, ty) eqns =
   522   let
   522   let
   523     val ctxt' = ctxt |> Proof_Context.theory_of |> Proof_Context.init_global
   523     val ctxt' = ctxt |> Proof_Context.theory_of |> Proof_Context.init_global
   524       |> Config.put Type_Infer_Context.const_sorts false;
   524       |> Config.put Type_Infer_Context.const_sorts false;
   525       (*avoid spurious fixed variables: there is no eigen context for equations*)
   525       (*avoid spurious fixed variables: there is no eigen context for equations*)
   526   in
   526   in
   527     map (apfst (fn (args, (rhs, some_abs)) => (args,
   527     map (apfst (fn (args, (some_abs, rhs)) => (args,
   528       (annotate ctxt' algbr eqngr (c, ty) args rhs, some_abs)))) eqns
   528       (some_abs, annotate ctxt' algbr eqngr (c, ty) args rhs)))) eqns
   529   end;
   529   end;
   530 
   530 
   531 
   531 
   532 (* abstract dictionary construction *)
   532 (* abstract dictionary construction *)
   533 
   533 
   655         val thm = Axclass.unoverload_conv ctxt (Thm.cterm_of ctxt raw_const);
   655         val thm = Axclass.unoverload_conv ctxt (Thm.cterm_of ctxt raw_const);
   656         val const = (apsnd Logic.unvarifyT_global o dest_Const o snd
   656         val const = (apsnd Logic.unvarifyT_global o dest_Const o snd
   657           o Logic.dest_equals o Thm.prop_of) thm;
   657           o Logic.dest_equals o Thm.prop_of) thm;
   658       in
   658       in
   659         ensure_const ctxt algbr eqngr permissive c
   659         ensure_const ctxt algbr eqngr permissive c
   660         ##>> translate_const ctxt algbr eqngr permissive (SOME thm) (const, NONE)
   660         ##>> translate_const ctxt algbr eqngr permissive (SOME thm) NONE const
   661         #>> (fn (c, IConst const') => ((c, (const', dom_length)), (thm, true)))
   661         #>> (fn (c, IConst const') => ((c, (const', dom_length)), (thm, true)))
   662       end;
   662       end;
   663     val stmt_inst =
   663     val stmt_inst =
   664       ensure_class ctxt algbr eqngr permissive class
   664       ensure_class ctxt algbr eqngr permissive class
   665       ##>> ensure_tyco ctxt algbr eqngr permissive tyco
   665       ##>> ensure_tyco ctxt algbr eqngr permissive tyco
   675       pair (ITyVar (unprefix "'" v))
   675       pair (ITyVar (unprefix "'" v))
   676   | translate_typ ctxt algbr eqngr permissive (Type (tyco, tys)) =
   676   | translate_typ ctxt algbr eqngr permissive (Type (tyco, tys)) =
   677       ensure_tyco ctxt algbr eqngr permissive tyco
   677       ensure_tyco ctxt algbr eqngr permissive tyco
   678       ##>> fold_map (translate_typ ctxt algbr eqngr permissive) tys
   678       ##>> fold_map (translate_typ ctxt algbr eqngr permissive) tys
   679       #>> (fn (tyco, tys) => tyco `%% tys)
   679       #>> (fn (tyco, tys) => tyco `%% tys)
   680 and translate_term ctxt algbr eqngr permissive some_thm (Const (c, ty), some_abs) =
   680 and translate_term ctxt algbr eqngr permissive some_thm some_abs (Const (c, ty)) =
   681       translate_app ctxt algbr eqngr permissive some_thm (((c, ty), []), some_abs)
   681       translate_app ctxt algbr eqngr permissive some_thm some_abs ((c, ty), [])
   682   | translate_term ctxt algbr eqngr permissive some_thm (Free (v, _), some_abs) =
   682   | translate_term ctxt algbr eqngr permissive some_thm some_abs (Free (v, _)) =
   683       pair (IVar (SOME v))
   683       pair (IVar (SOME v))
   684   | translate_term ctxt algbr eqngr permissive some_thm (Abs (v, ty, t), some_abs) =
   684   | translate_term ctxt algbr eqngr permissive some_thm some_abs (Abs (v, ty, t)) =
   685       let
   685       let
   686         val ((v', _), t') = Term.dest_abs_global (Abs (Name.desymbolize (SOME false) v, ty, t));
   686         val ((v', _), t') = Term.dest_abs_global (Abs (Name.desymbolize (SOME false) v, ty, t));
   687         val v'' = if Term.used_free v' t' then SOME v' else NONE
   687         val v'' = if Term.used_free v' t' then SOME v' else NONE
   688         val rty = fastype_of_tagged_term t'
   688         val rty = fastype_of_tagged_term t'
   689       in
   689       in
   690         translate_typ ctxt algbr eqngr permissive ty
   690         translate_typ ctxt algbr eqngr permissive ty
   691         ##>> translate_typ ctxt algbr eqngr permissive rty
   691         ##>> translate_typ ctxt algbr eqngr permissive rty
   692         ##>> translate_term ctxt algbr eqngr permissive some_thm (t', some_abs)
   692         ##>> translate_term ctxt algbr eqngr permissive some_thm some_abs t'
   693         #>> (fn ((ty, rty), t) => (v'', ty) `|=> (t, rty))
   693         #>> (fn ((ty, rty), t) => (v'', ty) `|=> (t, rty))
   694       end
   694       end
   695   | translate_term ctxt algbr eqngr permissive some_thm (t as _ $ _, some_abs) =
   695   | translate_term ctxt algbr eqngr permissive some_thm some_abs (t as _ $ _) =
   696       case strip_comb t
   696       case strip_comb t
   697        of (Const (c, ty), ts) =>
   697        of (Const (c, ty), ts) =>
   698             translate_app ctxt algbr eqngr permissive some_thm (((c, ty), ts), some_abs)
   698             translate_app ctxt algbr eqngr permissive some_thm some_abs ((c, ty), ts)
   699         | (t', ts) =>
   699         | (t', ts) =>
   700             translate_term ctxt algbr eqngr permissive some_thm (t', some_abs)
   700             translate_term ctxt algbr eqngr permissive some_thm some_abs t'
   701             ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts
   701             ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   702             #>> (fn (t, ts) => t `$$ ts)
   702             #>> (fn (t, ts) => t `$$ ts)
   703 and translate_eqn ctxt algbr eqngr permissive ((args, (rhs, some_abs)), (some_thm, proper)) =
   703 and translate_eqn ctxt algbr eqngr permissive ((args, (some_abs, rhs)), (some_thm, proper)) =
   704   fold_map (translate_term ctxt algbr eqngr permissive some_thm) args
   704   fold_map (uncurry (translate_term ctxt algbr eqngr permissive some_thm)) args
   705   ##>> translate_term ctxt algbr eqngr permissive some_thm (rhs, some_abs)
   705   ##>> translate_term ctxt algbr eqngr permissive some_thm some_abs rhs
   706   #>> rpair (some_thm, proper)
   706   #>> rpair (some_thm, proper)
   707 and translate_eqns ctxt algbr eqngr permissive eqns =
   707 and translate_eqns ctxt algbr eqngr permissive eqns =
   708   maybe_permissive (fold_map (translate_eqn ctxt algbr eqngr permissive) eqns)
   708   maybe_permissive (fold_map (translate_eqn ctxt algbr eqngr permissive) eqns)
   709 and translate_const ctxt algbr eqngr permissive some_thm ((c, ty), some_abs) (deps, program) =
   709 and translate_const ctxt algbr eqngr permissive some_thm some_abs (c, ty) (deps, program) =
   710   let
   710   let
   711     val thy = Proof_Context.theory_of ctxt;
   711     val thy = Proof_Context.theory_of ctxt;
   712     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   712     val _ = if (case some_abs of NONE => true | SOME abs => not (c = abs))
   713         andalso Code.is_abstr thy c
   713         andalso Code.is_abstr thy c
   714         then translation_error ctxt permissive some_thm deps
   714         then translation_error ctxt permissive some_thm deps
   730     #>> (fn (((c, typargs), dss), range :: dom) =>
   730     #>> (fn (((c, typargs), dss), range :: dom) =>
   731       IConst { sym = Constant c, typargs = typargs, dicts = dss,
   731       IConst { sym = Constant c, typargs = typargs, dicts = dss,
   732         dom = dom, range = range, annotation =
   732         dom = dom, range = range, annotation =
   733           if annotate then SOME (dom `--> range) else NONE })
   733           if annotate then SOME (dom `--> range) else NONE })
   734   end
   734   end
   735 and translate_app_const ctxt algbr eqngr permissive some_thm ((c_ty, ts), some_abs) =
   735 and translate_app_const ctxt algbr eqngr permissive some_thm some_abs (c_ty, ts) =
   736   translate_const ctxt algbr eqngr permissive some_thm (c_ty, some_abs)
   736   translate_const ctxt algbr eqngr permissive some_thm some_abs c_ty
   737   ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts
   737   ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   738   #>> (fn (t, ts) => t `$$ ts)
   738   #>> (fn (t, ts) => t `$$ ts)
   739 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, []) (c_ty, ts) =
   739 and translate_case ctxt algbr eqngr permissive some_thm (t_pos, []) (c_ty, ts) =
   740       let
   740       let
   741         fun project_term xs = nth xs t_pos;
   741         fun project_term xs = nth xs t_pos;
   742         val project_clause = the_single o nth_drop t_pos;
   742         val project_clause = the_single o nth_drop t_pos;
   743         val ty_case = project_term (binder_types (snd c_ty));
   743         val ty_case = project_term (binder_types (snd c_ty));
   744         fun distill_clauses ty_case t =
   744         fun distill_clauses ty_case t =
   745           map (fn ([pat], body) => (pat, body)) (distill_minimized_clause [ty_case] t)
   745           map (fn ([pat], body) => (pat, body)) (distill_minimized_clause [ty_case] t)
   746       in
   746       in
   747         translate_const ctxt algbr eqngr permissive some_thm (c_ty, NONE)
   747         translate_const ctxt algbr eqngr permissive some_thm NONE c_ty
   748         ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts
   748         ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   749         ##>> translate_typ ctxt algbr eqngr permissive ty_case
   749         ##>> translate_typ ctxt algbr eqngr permissive ty_case
   750         #>> (fn ((t_app, ts), ty_case) =>
   750         #>> (fn ((t_app, ts), ty_case) =>
   751             ICase { term = project_term ts, typ = ty_case,
   751             ICase { term = project_term ts, typ = ty_case,
   752               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses ty_case o project_clause) ts,
   752               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses ty_case o project_clause) ts,
   753               primitive = t_app `$$ ts })
   753               primitive = t_app `$$ ts })
   768           maps (fn ((constr as IConst { dom = tys, ... }, n), t) =>
   768           maps (fn ((constr as IConst { dom = tys, ... }, n), t) =>
   769             map (fn (pat_args, body) => (constr `$$ pat_args, body))
   769             map (fn (pat_args, body) => (constr `$$ pat_args, body))
   770               (distill_minimized_clause (take n tys) t))
   770               (distill_minimized_clause (take n tys) t))
   771                 (constrs ~~ ts_clause);
   771                 (constrs ~~ ts_clause);
   772       in
   772       in
   773         translate_const ctxt algbr eqngr permissive some_thm (c_ty, NONE)
   773         translate_const ctxt algbr eqngr permissive some_thm NONE c_ty
   774         ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) ts
   774         ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) ts
   775         ##>> translate_typ ctxt algbr eqngr permissive ty_case
   775         ##>> translate_typ ctxt algbr eqngr permissive ty_case
   776         ##>> fold_map (fn (c_ty, n) =>
   776         ##>> fold_map (fn (c_ty, n) =>
   777           translate_const ctxt algbr eqngr permissive some_thm (c_ty, NONE) #>> rpair n) constrs
   777           translate_const ctxt algbr eqngr permissive some_thm NONE c_ty #>> rpair n) constrs
   778         #>> (fn (((t_app, ts), ty_case), constrs) =>
   778         #>> (fn (((t_app, ts), ty_case), constrs) =>
   779             ICase { term = project_term ts, typ = ty_case,
   779             ICase { term = project_term ts, typ = ty_case,
   780               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses constrs o project_cases) ts,
   780               clauses = (filter_out (is_undefined_clause ctxt) o distill_clauses constrs o project_cases) ts,
   781               primitive = t_app `$$ ts })
   781               primitive = t_app `$$ ts })
   782       end
   782       end
   795       ##>> translate_typ ctxt algbr eqngr permissive rty
   795       ##>> translate_typ ctxt algbr eqngr permissive rty
   796       #>> (fn ((tys, t), rty) => map2 (fn (v, _) => pair (SOME v)) vs_tys tys `|==> (t, rty))
   796       #>> (fn ((tys, t), rty) => map2 (fn (v, _) => pair (SOME v)) vs_tys tys `|==> (t, rty))
   797     end
   797     end
   798   else if length ts > wanted then
   798   else if length ts > wanted then
   799     translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), take wanted ts)
   799     translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), take wanted ts)
   800     ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm o rpair NONE) (drop wanted ts)
   800     ##>> fold_map (translate_term ctxt algbr eqngr permissive some_thm NONE) (drop wanted ts)
   801     #>> (fn (t, ts) => t `$$ ts)
   801     #>> (fn (t, ts) => t `$$ ts)
   802   else
   802   else
   803     translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), ts)
   803     translate_case ctxt algbr eqngr permissive some_thm pattern_schema ((c, ty), ts)
   804 and translate_app ctxt algbr eqngr permissive some_thm (c_ty_ts as ((c, _), _), some_abs) =
   804 and translate_app ctxt algbr eqngr permissive some_thm some_abs (c_ty_ts as ((c, _), _)) =
   805   case Code.get_case_schema (Proof_Context.theory_of ctxt) c
   805   case Code.get_case_schema (Proof_Context.theory_of ctxt) c
   806    of SOME case_schema => translate_app_case ctxt algbr eqngr permissive some_thm case_schema c_ty_ts
   806    of SOME case_schema => translate_app_case ctxt algbr eqngr permissive some_thm case_schema c_ty_ts
   807     | NONE => translate_app_const ctxt algbr eqngr permissive some_thm (c_ty_ts, some_abs)
   807     | NONE => translate_app_const ctxt algbr eqngr permissive some_thm some_abs c_ty_ts
   808 and translate_tyvar_sort ctxt (algbr as (proj_sort, _)) eqngr permissive (v, sort) =
   808 and translate_tyvar_sort ctxt (algbr as (proj_sort, _)) eqngr permissive (v, sort) =
   809   fold_map (ensure_class ctxt algbr eqngr permissive) (proj_sort sort)
   809   fold_map (ensure_class ctxt algbr eqngr permissive) (proj_sort sort)
   810   #>> (fn sort => (unprefix "'" v, sort))
   810   #>> (fn sort => (unprefix "'" v, sort))
   811 and translate_dicts ctxt algbr eqngr permissive some_thm (ty, sort) =
   811 and translate_dicts ctxt algbr eqngr permissive some_thm (ty, sort) =
   812   let
   812   let
   901     val t' = annotate ctxt algbr eqngr (\<^const_name>\<open>Pure.dummy_pattern\<close>, ty) [] t;
   901     val t' = annotate ctxt algbr eqngr (\<^const_name>\<open>Pure.dummy_pattern\<close>, ty) [] t;
   902     val dummy_constant = Constant \<^const_name>\<open>Pure.dummy_pattern\<close>;
   902     val dummy_constant = Constant \<^const_name>\<open>Pure.dummy_pattern\<close>;
   903     val stmt_value =
   903     val stmt_value =
   904       fold_map (translate_tyvar_sort ctxt algbr eqngr false) vs
   904       fold_map (translate_tyvar_sort ctxt algbr eqngr false) vs
   905       ##>> translate_typ ctxt algbr eqngr false ty
   905       ##>> translate_typ ctxt algbr eqngr false ty
   906       ##>> translate_term ctxt algbr eqngr false NONE (t', NONE)
   906       ##>> translate_term ctxt algbr eqngr false NONE NONE t'
   907       #>> (fn ((vs, ty), t) => Fun
   907       #>> (fn ((vs, ty), t) => Fun
   908         (((vs, ty), [(([], t), (NONE, true))]), NONE));
   908         (((vs, ty), [(([], t), (NONE, true))]), NONE));
   909     fun term_value (_, program1) =
   909     fun term_value (_, program1) =
   910       let
   910       let
   911         val Fun ((vs_ty, [(([], t), _)]), _) =
   911         val Fun ((vs_ty, [(([], t), _)]), _) =