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