src/Tools/isac/MathEngBasic/thmC.sml
author wneuper <walther.neuper@jku.at>
Mon, 19 Jul 2021 18:29:46 +0200
changeset 60337 cbad4e18e91b
parent 60296 81b6519da42b
child 60360 49680d595342
permissions -rw-r--r--
cleanup after "eliminate ThmC.numerals_to_Free"
     1 (* Title:  BaseDefinitions/thmC.sml
     2    Author: Walther Neuper
     3    (c) due to copyright terms
     4 
     5 This structure could be dropped due to improved reflection in Isabelle;
     6 but ThmC.sym_thm requires still an identifying string thm_id.
     7 *)
     8 signature THEOREM_ISAC =
     9 sig
    10   type T = ThmC_Def.T
    11   type id = ThmC_Def.id (* shortest possible *)
    12   type long_id          (* e.g. "Test.radd_left_commute"*)
    13 
    14   val cut_id: string -> id
    15   val long_id: T -> long_id
    16   val string_of_thm: thm -> string
    17   val string_of_thms: thm list -> string
    18   val id_of_thm: thm -> id
    19   val of_thm: thm -> T
    20   val from_rule : Rule.rule -> T
    21   val member': id list -> Rule.rule -> bool
    22 
    23   val is_sym: id -> bool
    24   val thm_from_thy: theory -> ThmC_Def.id -> thm
    25 
    26   val revert_sym_rule: theory -> Rule.rule -> Rule.rule
    27 
    28   val make_rule: Proof.context -> bool -> string * Position.T -> Rule_Def.rule
    29 
    30 \<^isac_test>\<open>
    31   val dest_eq_concl: thm -> term * term
    32   val string_of_thm_in_thy: theory -> thm -> string
    33   val id_drop_sym: id -> id
    34 \<close>
    35   val make_sym_rule: Rule.rule -> Rule.rule
    36   val make_sym_rule_set: Rule_Set.T -> Rule_Set.T
    37   val sym_thm: thm -> thm
    38 end
    39 
    40 (**)
    41 structure ThmC(**): THEOREM_ISAC(**) =
    42 struct
    43 (**)
    44 
    45 (** types and conversions **)
    46 
    47 type T = ThmC_Def.T;
    48 type id = ThmC_Def.id;
    49 type long_id = string;
    50 
    51 fun long_id (thmID, _) = thmID |> Global_Theory.get_thm (ThyC.Isac ()) |> Thm.get_name_hint
    52 fun cut_id dn = last_elem (space_explode "." dn); (*the cut_id is the key into Know_Store*)
    53 
    54 val string_of_thm = ThmC_Def.string_of_thm;
    55 val string_of_thms = ThmC_Def.string_of_thms;
    56 
    57 fun id_of_thm thm = thm |> Thm.get_name_hint |> cut_id;
    58 fun of_thm thm = (id_of_thm thm, thm);
    59 fun from_rule (Rule.Thm (id, thm)) = (id, thm)
    60   | from_rule r = raise ERROR ("rule2thm': not defined for " ^ Rule.to_string r);
    61 \<^isac_test>\<open>
    62 fun string_of_thm_in_thy thy thm = UnparseC.term_in_ctxt (ThyC.to_ctxt thy) (Thm.prop_of thm);
    63 \<close>
    64 fun member' thmIDs thm = (member op = thmIDs (Rule.thm_id thm))
    65   handle ERROR _ => false
    66 
    67 
    68 (** handle symmetric equalities, generated by deriving input terms **)
    69 
    70 fun is_sym id =
    71   case Symbol.explode id of "s" :: "y" :: "m" :: "_" :: _ => true
    72   | _ => false;
    73 fun id_drop_sym id =
    74   case Symbol.explode id of "s" :: "y" :: "m" :: "_" :: id => implode id
    75   | _ => id
    76 
    77 (* get the theorem associated with the xstring-identifier;
    78    if the identifier starts with "sym_" then swap "lhs = rhs" around "=";
    79    in case identifiers starting with "#" come from Eval and
    80    get an ad-hoc theorem (containing numerals only) -- rejected here
    81 *)
    82 fun thm_from_thy thy thmid =
    83   case Symbol.explode thmid of
    84     "s" :: "y" :: "m" :: "_" :: "#" :: _ =>
    85       raise ERROR ("thm_from_thy not impl.for " ^ thmid)
    86   | "s" :: "y" :: "m" :: "_" :: id =>
    87       ((Global_Theory.get_thm thy) (implode id)) RS sym
    88   | "#" :: _ =>
    89       raise ERROR ("thm_from_thy not impl.for " ^ thmid)
    90   | _ =>
    91       thmid |> Global_Theory.get_thm thy
    92 
    93 fun dest_eq_concl thm =
    94   (case try (HOLogic.dest_eq o HOLogic.dest_Trueprop o Logic.strip_imp_concl o Thm.prop_of) thm of
    95     NONE => raise THM ("dest_eq_concl: conclusion needs to be HOL equality", 0, [thm])
    96   | SOME eq => eq);
    97 
    98 (* A1==>...==> An ==> (Lhs = Rhs) goes to A1 ==>...==> An ==> (Rhs = Lhs) *)
    99 (*NB: careful instantiation avoids shifting of schematic variables*)
   100 fun sym_thm thm =
   101   let
   102     val thy = Thm.theory_of_thm thm;
   103     val certT = Thm.global_ctyp_of thy;
   104     val cert = Thm.global_cterm_of thy;
   105 
   106     val (lhs, rhs) = dest_eq_concl thm |> apply2 cert;
   107     val A = Thm.typ_of_cterm lhs;
   108 
   109     val sym_rule = Thm.lift_rule (Thm.cprop_of thm) @{thm sym};
   110     val (t, s) = dest_eq_concl sym_rule;
   111 
   112     val instT = map (rpair A) (Term.add_tvars t []);
   113     val (t', s') = (t, s) |> apply2 (dest_Var o Term_Subst.instantiate (instT, []));
   114 
   115     val cinstT = map (apsnd certT) instT;
   116     val cinst = [(s', lhs), (t', rhs)];
   117   in
   118     thm
   119     |> Thm.implies_elim (Thm.instantiate (cinstT, cinst) sym_rule)
   120     |> Thm.put_name_hint (Thm.get_name_hint thm)
   121   end;
   122 
   123 fun make_sym_rule_set Rule_Set.Empty = Rule_Set.Empty
   124   | make_sym_rule_set (Rule_Def.Repeat {id, scr, calc, errpatts, erls, srls, rules, rew_ord, preconds}) =
   125     Rule_Def.Repeat {id = "sym_" ^ id, scr = scr, calc = calc, errpatts = errpatts, erls = erls, srls = srls, 
   126       rules = rules, rew_ord = rew_ord, preconds = preconds}
   127   | make_sym_rule_set (Rule_Set.Sequence {id, scr, calc, errpatts, erls, srls, rules, rew_ord, preconds}) =
   128     Rule_Set.Sequence {id = "sym_" ^ id, scr = scr, calc = calc, errpatts = errpatts, erls = erls, srls = srls, 
   129       rules = rules, rew_ord = rew_ord, preconds = preconds}
   130   | make_sym_rule_set (Rule_Set.Rrls {id, scr, calc, errpatts, erls, prepat, rew_ord}) = 
   131     Rule_Set.Rrls {id = "sym_" ^ id, scr = scr, calc = calc,  errpatts = errpatts, erls = erls,
   132       prepat = prepat, rew_ord = rew_ord}
   133 
   134 (* toggles sym_* and keeps "#:" for ad-hoc theorems *)
   135 fun make_sym_rule (Rule.Thm (thmID, thm)) =
   136       let
   137         val thm' = sym_thm thm
   138         val thmID' = case Symbol.explode thmID of
   139           "s" :: "y" :: "m" :: "_" :: id => implode id
   140         | "#" :: ":" :: _ => "#: " ^ string_of_thm thm'
   141         | _ => "sym_" ^ thmID
   142       in Rule.Thm (thmID', thm') end
   143   | make_sym_rule (Rule.Rls_ rls) = Rule.Rls_ (make_sym_rule_set rls)
   144   | make_sym_rule r = raise ERROR ("make_sym_rule: not for " ^  Rule.to_string r)
   145 
   146 fun revert_sym_rule thy (Rule.Thm (id, thm)) =
   147       if is_sym (cut_id id)
   148       then 
   149         let 
   150           val id' = id_drop_sym id
   151           val thm' = thm_from_thy thy id'
   152           val id'' = Thm.get_name_hint thm'
   153         in Rule.Thm (id'', thm') end
   154       else Rule.Thm (Thm.get_name_hint thm, thm)
   155   | revert_sym_rule _ rule = raise ERROR ("revert_sym_rule: NOT for " ^ Rule.to_string rule)
   156 
   157 
   158 (* ML antiquotations *)
   159 
   160 val sym_prefix = "sym_";
   161 
   162 fun make_rule ctxt symmetric (xname, pos) =
   163   let
   164     val _ =
   165       if String.isPrefix sym_prefix xname
   166       then error ("Bad theorem name with sym-prefix " ^ quote xname ^ Position.here pos) else ();
   167 
   168     val context = Context.Proof ctxt;
   169     val facts = Global_Theory.facts_of (Proof_Context.theory_of ctxt);
   170     val {name, dynamic, thms, ...} = Facts.retrieve context facts (xname, pos);
   171     val thm =
   172       if dynamic then error ("Bad dynamic fact " ^ quote name ^ Position.here pos)
   173       else Facts.the_single (name, pos) thms;
   174     val (xname', thm') = if symmetric then (sym_prefix ^ xname, thm RS sym) else (xname, thm);
   175   in Rule.Thm (xname', thm') end;
   176 
   177 fun antiquotation binding sym =
   178   ML_Antiquotation.value_embedded binding
   179     (Scan.lift Args.embedded_position >> (fn name =>
   180       "ThmC.make_rule ML_context " ^ Bool.toString sym ^
   181         ML_Syntax.print_pair ML_Syntax.print_string ML_Syntax.print_position name));
   182 
   183 val _ =
   184   Theory.setup
   185     (antiquotation \<^binding>\<open>rule_thm\<close> false #>
   186      antiquotation \<^binding>\<open>rule_thm_sym\<close> true);
   187 
   188 (**)end(**)