src/Pure/Isar/expression.ML
changeset 52140 88a69da5d3fa
parent 52119 90ba620333d0
child 52148 893b15200ec1
equal deleted inserted replaced
52139:40fe6b80b481 52140:88a69da5d3fa
   808 
   808 
   809 (*** Interpretation ***)
   809 (*** Interpretation ***)
   810 
   810 
   811 local
   811 local
   812 
   812 
   813 fun read_with_extended_syntax parse_prop deps ctxt props =
   813 (* reading *)
       
   814 
       
   815 fun read_with_extended_syntax prep_prop deps ctxt props =
   814   let
   816   let
   815     val deps_ctxt = fold Locale.activate_declarations deps ctxt;
   817     val deps_ctxt = fold Locale.activate_declarations deps ctxt;
   816   in
   818   in
   817     map (parse_prop deps_ctxt o snd) props |> Syntax.check_terms deps_ctxt
   819     map (prep_prop deps_ctxt o snd) props |> Syntax.check_terms deps_ctxt
   818       |> Variable.export_terms deps_ctxt ctxt
   820       |> Variable.export_terms deps_ctxt ctxt
   819   end;
   821   end;
   820 
   822 
   821 fun read_interpretation prep_expr parse_prop prep_attr expression raw_eqns initial_ctxt =
   823 fun read_interpretation prep_expr prep_prop prep_attr expression raw_eqns initial_ctxt =
   822   let
   824   let
   823     val ((propss, deps, export), expr_ctxt) = prep_expr expression initial_ctxt;
   825     val ((propss, deps, export), expr_ctxt) = prep_expr expression initial_ctxt;
   824     val eqns = read_with_extended_syntax parse_prop deps expr_ctxt raw_eqns;
   826     val eqns = read_with_extended_syntax prep_prop deps expr_ctxt raw_eqns;
   825     val attrss = map (apsnd (map (prep_attr (Proof_Context.theory_of initial_ctxt))) o fst) raw_eqns;
   827     val attrss = map (apsnd (map (prep_attr (Proof_Context.theory_of initial_ctxt))) o fst) raw_eqns;
   826     val goal_ctxt = fold Variable.auto_fixes eqns expr_ctxt;
   828     val goal_ctxt = fold Variable.auto_fixes eqns expr_ctxt;
   827     val export' = Variable.export_morphism goal_ctxt expr_ctxt;
   829     val export' = Variable.export_morphism goal_ctxt expr_ctxt;
   828   in (((propss, deps, export, export'), (eqns, attrss)), goal_ctxt) end;
   830   in (((propss, deps, export, export'), (eqns, attrss)), goal_ctxt) end;
   829 
   831 
       
   832 
       
   833 (* generic interpretation machinery *)
       
   834 
   830 fun meta_rewrite eqns ctxt = (map (Local_Defs.meta_rewrite_rule ctxt #> Drule.abs_def) (maps snd eqns), ctxt);
   835 fun meta_rewrite eqns ctxt = (map (Local_Defs.meta_rewrite_rule ctxt #> Drule.abs_def) (maps snd eqns), ctxt);
   831 
   836 
   832 fun note_eqns_register note activate deps witss eqns attrss export export' ctxt =
   837 fun note_eqns_register note activate deps witss eqns attrss export export' ctxt =
   833   let
   838   let
   834     val facts = 
   839     val facts = map2 (fn attrs => fn eqn =>
   835       (attrss ~~ map (fn eqn => [([Morphism.thm (export' $> export) eqn], [])]) eqns);
   840       (attrs, [([Morphism.thm (export' $> export) eqn], [])])) attrss eqns;
   836     val (eqns', ctxt') = ctxt
   841     val (eqns', ctxt') = ctxt
   837       |> note Thm.lemmaK facts
   842       |> note Thm.lemmaK facts
   838       |-> meta_rewrite;
   843       |-> meta_rewrite;
   839     val dep_morphs = map2 (fn (dep, morph) => fn wits =>
   844     val dep_morphs = map2 (fn (dep, morph) => fn wits =>
   840       (dep, morph $> Element.satisfy_morphism (map (Element.transform_witness export') wits))) deps witss;
   845       (dep, morph $> Element.satisfy_morphism (map (Element.transform_witness export') wits))) deps witss;
   843   in
   848   in
   844     ctxt'
   849     ctxt'
   845     |> fold activate' dep_morphs
   850     |> fold activate' dep_morphs
   846   end;
   851   end;
   847 
   852 
   848 fun generic_interpretation prep_expr parse_prop prep_attr setup_proof note add_registration
   853 fun generic_interpretation prep_expr prep_prop prep_attr setup_proof note activate
   849     expression raw_eqns initial_ctxt = 
   854     expression raw_eqns initial_ctxt = 
   850   let
   855   let
   851     val (((propss, deps, export, export'), (eqns, attrss)), goal_ctxt) = 
   856     val (((propss, deps, export, export'), (eqns, attrss)), goal_ctxt) = 
   852       read_interpretation prep_expr parse_prop prep_attr expression raw_eqns initial_ctxt;
   857       read_interpretation prep_expr prep_prop prep_attr expression raw_eqns initial_ctxt;
   853     fun after_qed witss eqns =
   858     fun after_qed witss eqns =
   854       note_eqns_register note add_registration deps witss eqns attrss export export';
   859       note_eqns_register note activate deps witss eqns attrss export export';
   855   in setup_proof after_qed propss eqns goal_ctxt end;
   860   in setup_proof after_qed propss eqns goal_ctxt end;
   856 
   861 
   857 val activate_proof = Context.proof_map ooo Locale.add_registration;
   862 
   858 val activate_local_theory = Local_Theory.surface_target ooo activate_proof;
   863 (* various flavours of interpretation *)
   859 val add_registration = Local_Theory.raw_theory o Context.theory_map ooo Locale.add_registration;
   864 
   860 fun add_dependency locale dep_morph mixin export =
   865 fun assert_not_theory lthy = if Named_Target.is_theory lthy
   861   (Local_Theory.raw_theory ooo Locale.add_dependency locale) dep_morph mixin export
   866   then error "Not possible on level of global theory" else ();
   862   #> activate_local_theory dep_morph mixin export;
   867 
   863 fun add_dependency_global locale = Proof_Context.background_theory ooo Locale.add_dependency locale;
   868 fun gen_interpret prep_expr prep_prop prep_attr expression raw_eqns int state =
   864 
       
   865 fun gen_interpret prep_expr parse_prop prep_attr expression raw_eqns int state =
       
   866   let
   869   let
   867     val _ = Proof.assert_forward_or_chain state;
   870     val _ = Proof.assert_forward_or_chain state;
   868     val ctxt = Proof.context_of state;
   871     val ctxt = Proof.context_of state;
   869     fun lift_after_qed after_qed witss eqns = Proof.map_context (after_qed witss eqns) #> Proof.reset_facts;
   872     fun lift_after_qed after_qed witss eqns = Proof.map_context (after_qed witss eqns) #> Proof.reset_facts;
   870     fun setup_proof after_qed propss eqns goal_ctxt = 
   873     fun setup_proof after_qed propss eqns goal_ctxt = 
   871       Element.witness_local_proof_eqs (lift_after_qed after_qed) "interpret" propss eqns goal_ctxt int state;
   874       Element.witness_local_proof_eqs (lift_after_qed after_qed) "interpret" propss eqns goal_ctxt int state;
   872   in
   875   in
   873     generic_interpretation prep_expr parse_prop prep_attr setup_proof
   876     generic_interpretation prep_expr prep_prop prep_attr setup_proof
   874       Attrib.local_notes activate_proof expression raw_eqns ctxt
   877       Attrib.local_notes (Context.proof_map ooo Locale.add_registration) expression raw_eqns ctxt
   875   end;
   878   end;
   876 
   879 
   877 fun gen_interpretation prep_expr parse_prop prep_attr expression raw_eqns lthy =
   880 fun gen_interpretation prep_expr prep_prop prep_attr expression raw_eqns lthy =
   878   let
   881   if Named_Target.is_theory lthy
   879     val is_theory = Option.map #target (Named_Target.peek lthy) = SOME ""
   882   then 
   880       andalso Local_Theory.level lthy = 1;
       
   881     val activate = if is_theory then add_registration else activate_local_theory;
       
   882     val mark_brittle = if is_theory then I else Local_Theory.mark_brittle;
       
   883   in
       
   884     lthy
   883     lthy
   885     |> mark_brittle
   884     |> generic_interpretation prep_expr prep_prop prep_attr Element.witness_proof_eqs
   886     |> generic_interpretation prep_expr parse_prop prep_attr Element.witness_proof_eqs
   885         Local_Theory.notes_kind Local_Theory.add_registration expression raw_eqns
   887         Local_Theory.notes_kind activate expression raw_eqns
   886   else
   888   end;
       
   889 
       
   890 fun gen_sublocale prep_expr parse_prop prep_attr expression raw_eqns lthy =
       
   891   let
       
   892     val locale =
       
   893       case Option.map #target (Named_Target.peek lthy) of
       
   894           SOME locale => locale
       
   895         | _ => error "Not in a locale target";
       
   896   in
       
   897     lthy
   887     lthy
   898     |> generic_interpretation prep_expr parse_prop prep_attr Element.witness_proof_eqs
   888     |> generic_interpretation prep_expr prep_prop prep_attr Element.witness_proof_eqs
   899         Local_Theory.notes_kind (add_dependency locale) expression raw_eqns
   889         Local_Theory.notes_kind Local_Theory.activate expression raw_eqns;
       
   890 
       
   891 fun gen_sublocale prep_expr prep_prop prep_attr expression raw_eqns lthy =
       
   892   let
       
   893     val _ = assert_not_theory lthy;
       
   894     val locale = Named_Target.the_name lthy;
       
   895   in
       
   896     lthy
       
   897     |> generic_interpretation prep_expr prep_prop prep_attr Element.witness_proof_eqs
       
   898         Local_Theory.notes_kind (Local_Theory.add_dependency locale) expression raw_eqns
   900   end;
   899   end;
   901   
   900   
   902 fun gen_sublocale_global prep_expr prep_loc parse_prop prep_attr before_exit raw_locale expression raw_eqns thy =
   901 fun gen_sublocale_global prep_expr prep_loc prep_prop prep_attr before_exit raw_locale expression raw_eqns thy =
   903   let
   902   let
   904     val locale = prep_loc thy raw_locale;
   903     val locale = prep_loc thy raw_locale;
       
   904     val add_dependency_global = Proof_Context.background_theory ooo Locale.add_dependency locale;
   905   in
   905   in
   906     thy
   906     thy
   907     |> Named_Target.init before_exit locale
   907     |> Named_Target.init before_exit locale
   908     |> generic_interpretation prep_expr parse_prop prep_attr Element.witness_proof_eqs
   908     |> generic_interpretation prep_expr prep_prop prep_attr Element.witness_proof_eqs
   909         Local_Theory.notes_kind (add_dependency_global locale) expression raw_eqns
   909         Local_Theory.notes_kind add_dependency_global expression raw_eqns
   910   end;
   910   end;
   911 
   911 
   912 in
   912 in
   913 
   913 
   914 fun permanent_interpretation expression raw_eqns lthy =
   914 fun permanent_interpretation expression raw_eqns lthy =
   915   let
   915   let
   916     val _ = Local_Theory.assert_bottom true lthy;
   916     val _ = Local_Theory.assert_bottom true lthy;
   917     val target = case Named_Target.peek lthy of
   917     val target = Named_Target.the_name lthy;
   918           SOME { target, ... } => target
   918     val subscribe = if target = "" then Local_Theory.add_registration
   919         | NONE => error "Not in a named target";
   919       else Local_Theory.add_dependency target;
   920     val is_theory = (target = "");
       
   921     val activate = if is_theory then add_registration else add_dependency target;
       
   922   in
   920   in
   923     lthy
   921     lthy
   924     |> generic_interpretation cert_goal_expression (K I) (K I) Element.witness_proof_eqs
   922     |> generic_interpretation cert_goal_expression (K I) (K I) Element.witness_proof_eqs
   925         Local_Theory.notes_kind activate expression raw_eqns
   923         Local_Theory.notes_kind subscribe expression raw_eqns
   926   end;
   924   end;
   927 
   925 
   928 fun ephemeral_interpretation expression raw_eqns lthy =
   926 fun ephemeral_interpretation expression raw_eqns lthy =
   929   let
   927   let
   930     val _ = if Option.map #target (Named_Target.peek lthy) = SOME ""
   928     val _ = assert_not_theory lthy;
   931       andalso Local_Theory.level lthy = 1
       
   932       then error "Not possible on level of global theory" else ();
       
   933   in
   929   in
   934     lthy
   930     lthy
   935     |> Local_Theory.mark_brittle
       
   936     |> generic_interpretation cert_goal_expression (K I) (K I) Element.witness_proof_eqs
   931     |> generic_interpretation cert_goal_expression (K I) (K I) Element.witness_proof_eqs
   937         Local_Theory.notes_kind activate_local_theory expression raw_eqns
   932         Local_Theory.notes_kind Local_Theory.activate expression raw_eqns
   938   end;
   933   end;
   939 
   934 
   940 fun interpret x = gen_interpret cert_goal_expression (K I) (K I) x;
   935 fun interpret x = gen_interpret cert_goal_expression (K I) (K I) x;
   941 fun interpret_cmd x =
   936 fun interpret_cmd x =
   942   gen_interpret read_goal_expression Syntax.parse_prop Attrib.intern_src x;
   937   gen_interpret read_goal_expression Syntax.parse_prop Attrib.intern_src x;