wenzelm@250
|
1 |
(* Title: Pure/thm.ML
|
wenzelm@250
|
2 |
Author: Lawrence C Paulson, Cambridge University Computer Laboratory
|
wenzelm@29269
|
3 |
Author: Makarius
|
lcp@229
|
4 |
|
wenzelm@16425
|
5 |
The very core of Isabelle's Meta Logic: certified types and terms,
|
wenzelm@28321
|
6 |
derivations, theorems, framework rules (including lifting and
|
wenzelm@28321
|
7 |
resolution), oracles.
|
clasohm@0
|
8 |
*)
|
clasohm@0
|
9 |
|
wenzelm@6089
|
10 |
signature BASIC_THM =
|
paulson@1503
|
11 |
sig
|
wenzelm@1160
|
12 |
(*certified types*)
|
wenzelm@387
|
13 |
type ctyp
|
wenzelm@16656
|
14 |
val rep_ctyp: ctyp ->
|
wenzelm@26631
|
15 |
{thy_ref: theory_ref,
|
wenzelm@16656
|
16 |
T: typ,
|
wenzelm@20512
|
17 |
maxidx: int,
|
wenzelm@39935
|
18 |
sorts: sort Ord_List.T}
|
wenzelm@16425
|
19 |
val theory_of_ctyp: ctyp -> theory
|
wenzelm@16425
|
20 |
val typ_of: ctyp -> typ
|
wenzelm@16425
|
21 |
val ctyp_of: theory -> typ -> ctyp
|
wenzelm@1160
|
22 |
|
wenzelm@1160
|
23 |
(*certified terms*)
|
wenzelm@1160
|
24 |
type cterm
|
wenzelm@22584
|
25 |
exception CTERM of string * cterm list
|
wenzelm@16601
|
26 |
val rep_cterm: cterm ->
|
wenzelm@26631
|
27 |
{thy_ref: theory_ref,
|
wenzelm@16656
|
28 |
t: term,
|
wenzelm@16656
|
29 |
T: typ,
|
wenzelm@16656
|
30 |
maxidx: int,
|
wenzelm@39935
|
31 |
sorts: sort Ord_List.T}
|
wenzelm@28354
|
32 |
val crep_cterm: cterm ->
|
wenzelm@39935
|
33 |
{thy_ref: theory_ref, t: term, T: ctyp, maxidx: int, sorts: sort Ord_List.T}
|
wenzelm@16425
|
34 |
val theory_of_cterm: cterm -> theory
|
wenzelm@16425
|
35 |
val term_of: cterm -> term
|
wenzelm@16425
|
36 |
val cterm_of: theory -> term -> cterm
|
wenzelm@16425
|
37 |
val ctyp_of_term: cterm -> ctyp
|
wenzelm@1160
|
38 |
|
wenzelm@28321
|
39 |
(*theorems*)
|
wenzelm@1160
|
40 |
type thm
|
wenzelm@23601
|
41 |
type conv = cterm -> thm
|
wenzelm@16425
|
42 |
val rep_thm: thm ->
|
wenzelm@26631
|
43 |
{thy_ref: theory_ref,
|
wenzelm@28017
|
44 |
tags: Properties.T,
|
wenzelm@16425
|
45 |
maxidx: int,
|
wenzelm@39935
|
46 |
shyps: sort Ord_List.T,
|
wenzelm@39935
|
47 |
hyps: term Ord_List.T,
|
wenzelm@16425
|
48 |
tpairs: (term * term) list,
|
wenzelm@16425
|
49 |
prop: term}
|
wenzelm@16425
|
50 |
val crep_thm: thm ->
|
wenzelm@26631
|
51 |
{thy_ref: theory_ref,
|
wenzelm@28017
|
52 |
tags: Properties.T,
|
wenzelm@16425
|
53 |
maxidx: int,
|
wenzelm@39935
|
54 |
shyps: sort Ord_List.T,
|
wenzelm@39935
|
55 |
hyps: cterm Ord_List.T,
|
wenzelm@16425
|
56 |
tpairs: (cterm * cterm) list,
|
wenzelm@16425
|
57 |
prop: cterm}
|
wenzelm@6089
|
58 |
exception THM of string * int * thm list
|
wenzelm@16425
|
59 |
val theory_of_thm: thm -> theory
|
wenzelm@16425
|
60 |
val prop_of: thm -> term
|
wenzelm@16656
|
61 |
val concl_of: thm -> term
|
wenzelm@16425
|
62 |
val prems_of: thm -> term list
|
wenzelm@16425
|
63 |
val nprems_of: thm -> int
|
wenzelm@16425
|
64 |
val cprop_of: thm -> cterm
|
wenzelm@18145
|
65 |
val cprem_of: thm -> int -> cterm
|
wenzelm@250
|
66 |
end;
|
clasohm@0
|
67 |
|
wenzelm@6089
|
68 |
signature THM =
|
wenzelm@6089
|
69 |
sig
|
wenzelm@6089
|
70 |
include BASIC_THM
|
wenzelm@16425
|
71 |
val dest_ctyp: ctyp -> ctyp list
|
wenzelm@16425
|
72 |
val dest_comb: cterm -> cterm * cterm
|
wenzelm@22909
|
73 |
val dest_fun: cterm -> cterm
|
wenzelm@20580
|
74 |
val dest_arg: cterm -> cterm
|
wenzelm@22909
|
75 |
val dest_fun2: cterm -> cterm
|
wenzelm@22909
|
76 |
val dest_arg1: cterm -> cterm
|
wenzelm@16425
|
77 |
val dest_abs: string option -> cterm -> cterm * cterm
|
wenzelm@16425
|
78 |
val capply: cterm -> cterm -> cterm
|
wenzelm@32204
|
79 |
val cabs_name: string * cterm -> cterm -> cterm
|
wenzelm@16425
|
80 |
val cabs: cterm -> cterm -> cterm
|
wenzelm@31945
|
81 |
val adjust_maxidx_cterm: int -> cterm -> cterm
|
wenzelm@31945
|
82 |
val incr_indexes_cterm: int -> cterm -> cterm
|
wenzelm@31945
|
83 |
val match: cterm * cterm -> (ctyp * ctyp) list * (cterm * cterm) list
|
wenzelm@31945
|
84 |
val first_order_match: cterm * cterm -> (ctyp * ctyp) list * (cterm * cterm) list
|
wenzelm@31947
|
85 |
val fold_terms: (term -> 'a -> 'a) -> thm -> 'a -> 'a
|
wenzelm@16945
|
86 |
val terms_of_tpairs: (term * term) list -> term list
|
wenzelm@31945
|
87 |
val full_prop_of: thm -> term
|
wenzelm@19881
|
88 |
val maxidx_of: thm -> int
|
wenzelm@19910
|
89 |
val maxidx_thm: thm -> int -> int
|
wenzelm@19881
|
90 |
val hyps_of: thm -> term list
|
wenzelm@38957
|
91 |
val tpairs_of: thm -> (term * term) list
|
wenzelm@31945
|
92 |
val no_prems: thm -> bool
|
wenzelm@31945
|
93 |
val major_prem_of: thm -> term
|
wenzelm@38957
|
94 |
val transfer: theory -> thm -> thm
|
wenzelm@38957
|
95 |
val weaken: cterm -> thm -> thm
|
wenzelm@38957
|
96 |
val weaken_sorts: sort list -> cterm -> cterm
|
wenzelm@38957
|
97 |
val extra_shyps: thm -> sort list
|
wenzelm@32730
|
98 |
val join_proofs: thm list -> unit
|
wenzelm@32730
|
99 |
val proof_body_of: thm -> proof_body
|
wenzelm@32730
|
100 |
val proof_of: thm -> proof
|
wenzelm@32730
|
101 |
val status_of: thm -> {oracle: bool, unfinished: bool, failed: bool}
|
wenzelm@32730
|
102 |
val future: thm future -> cterm -> thm
|
wenzelm@36753
|
103 |
val derivation_name: thm -> string
|
wenzelm@36753
|
104 |
val name_derivation: string -> thm -> thm
|
wenzelm@28675
|
105 |
val axiom: theory -> string -> thm
|
wenzelm@28675
|
106 |
val axioms_of: theory -> (string * thm) list
|
wenzelm@28017
|
107 |
val get_tags: thm -> Properties.T
|
wenzelm@28017
|
108 |
val map_tags: (Properties.T -> Properties.T) -> thm -> thm
|
berghofe@23781
|
109 |
val norm_proof: thm -> thm
|
wenzelm@20261
|
110 |
val adjust_maxidx_thm: int -> thm -> thm
|
wenzelm@38957
|
111 |
(*meta rules*)
|
wenzelm@38957
|
112 |
val assume: cterm -> thm
|
wenzelm@38957
|
113 |
val implies_intr: cterm -> thm -> thm
|
wenzelm@38957
|
114 |
val implies_elim: thm -> thm -> thm
|
wenzelm@38957
|
115 |
val forall_intr: cterm -> thm -> thm
|
wenzelm@38957
|
116 |
val forall_elim: cterm -> thm -> thm
|
wenzelm@38957
|
117 |
val reflexive: cterm -> thm
|
wenzelm@38957
|
118 |
val symmetric: thm -> thm
|
wenzelm@38957
|
119 |
val transitive: thm -> thm -> thm
|
wenzelm@38957
|
120 |
val beta_conversion: bool -> conv
|
wenzelm@38957
|
121 |
val eta_conversion: conv
|
wenzelm@38957
|
122 |
val eta_long_conversion: conv
|
wenzelm@38957
|
123 |
val abstract_rule: string -> cterm -> thm -> thm
|
wenzelm@38957
|
124 |
val combination: thm -> thm -> thm
|
wenzelm@38957
|
125 |
val equal_intr: thm -> thm -> thm
|
wenzelm@38957
|
126 |
val equal_elim: thm -> thm -> thm
|
wenzelm@38957
|
127 |
val flexflex_rule: thm -> thm Seq.seq
|
wenzelm@38957
|
128 |
val generalize: string list * string list -> int -> thm -> thm
|
wenzelm@38957
|
129 |
val instantiate: (ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm
|
wenzelm@38957
|
130 |
val instantiate_cterm: (ctyp * ctyp) list * (cterm * cterm) list -> cterm -> cterm
|
wenzelm@38957
|
131 |
val trivial: cterm -> thm
|
wenzelm@36341
|
132 |
val of_class: ctyp * class -> thm
|
wenzelm@36637
|
133 |
val strip_shyps: thm -> thm
|
wenzelm@36777
|
134 |
val unconstrainT: thm -> thm
|
wenzelm@38957
|
135 |
val varifyT_global': (string * sort) list -> thm -> ((string * sort) * indexname) list * thm
|
wenzelm@38957
|
136 |
val varifyT_global: thm -> thm
|
wenzelm@36638
|
137 |
val legacy_freezeT: thm -> thm
|
wenzelm@38957
|
138 |
val dest_state: thm * int -> (term * term) list * term list * term * term
|
wenzelm@38957
|
139 |
val lift_rule: cterm -> thm -> thm
|
wenzelm@38957
|
140 |
val incr_indexes: int -> thm -> thm
|
wenzelm@31945
|
141 |
val assumption: int -> thm -> thm Seq.seq
|
wenzelm@31945
|
142 |
val eq_assumption: int -> thm -> thm
|
wenzelm@31945
|
143 |
val rotate_rule: int -> int -> thm -> thm
|
wenzelm@31945
|
144 |
val permute_prems: int -> int -> thm -> thm
|
wenzelm@31945
|
145 |
val rename_params_rule: string list * int -> thm -> thm
|
wenzelm@38957
|
146 |
val rename_boundvars: term -> term -> thm -> thm
|
wenzelm@31945
|
147 |
val compose_no_flatten: bool -> thm * int -> int -> thm -> thm Seq.seq
|
wenzelm@31945
|
148 |
val bicompose: bool -> bool * thm * int -> int -> thm -> thm Seq.seq
|
wenzelm@31945
|
149 |
val biresolution: bool -> (bool * thm) list -> int -> thm -> thm Seq.seq
|
wenzelm@43229
|
150 |
val extern_oracles: Proof.context -> xstring list
|
wenzelm@30288
|
151 |
val add_oracle: binding * ('a -> cterm) -> theory -> (string * ('a -> thm)) * theory
|
wenzelm@6089
|
152 |
end;
|
wenzelm@6089
|
153 |
|
wenzelm@32590
|
154 |
structure Thm: THM =
|
wenzelm@250
|
155 |
struct
|
clasohm@0
|
156 |
|
wenzelm@387
|
157 |
(*** Certified terms and types ***)
|
wenzelm@387
|
158 |
|
wenzelm@250
|
159 |
(** certified types **)
|
lcp@229
|
160 |
|
wenzelm@32590
|
161 |
abstype ctyp = Ctyp of
|
wenzelm@20512
|
162 |
{thy_ref: theory_ref,
|
wenzelm@20512
|
163 |
T: typ,
|
wenzelm@20512
|
164 |
maxidx: int,
|
wenzelm@39935
|
165 |
sorts: sort Ord_List.T}
|
wenzelm@32590
|
166 |
with
|
lcp@229
|
167 |
|
wenzelm@26631
|
168 |
fun rep_ctyp (Ctyp args) = args;
|
wenzelm@16656
|
169 |
fun theory_of_ctyp (Ctyp {thy_ref, ...}) = Theory.deref thy_ref;
|
wenzelm@250
|
170 |
fun typ_of (Ctyp {T, ...}) = T;
|
lcp@229
|
171 |
|
wenzelm@16656
|
172 |
fun ctyp_of thy raw_T =
|
wenzelm@24143
|
173 |
let
|
wenzelm@24143
|
174 |
val T = Sign.certify_typ thy raw_T;
|
wenzelm@24143
|
175 |
val maxidx = Term.maxidx_of_typ T;
|
wenzelm@26640
|
176 |
val sorts = Sorts.insert_typ T [];
|
wenzelm@24143
|
177 |
in Ctyp {thy_ref = Theory.check_thy thy, T = T, maxidx = maxidx, sorts = sorts} end;
|
lcp@229
|
178 |
|
wenzelm@32791
|
179 |
fun dest_ctyp (Ctyp {thy_ref, T = Type (_, Ts), maxidx, sorts}) =
|
wenzelm@20512
|
180 |
map (fn T => Ctyp {thy_ref = thy_ref, T = T, maxidx = maxidx, sorts = sorts}) Ts
|
wenzelm@16679
|
181 |
| dest_ctyp cT = raise TYPE ("dest_ctyp", [typ_of cT], []);
|
berghofe@15087
|
182 |
|
wenzelm@250
|
183 |
|
wenzelm@250
|
184 |
|
wenzelm@250
|
185 |
(** certified terms **)
|
wenzelm@250
|
186 |
|
wenzelm@16601
|
187 |
(*certified terms with checked typ, maxidx, and sorts*)
|
wenzelm@32590
|
188 |
abstype cterm = Cterm of
|
wenzelm@16601
|
189 |
{thy_ref: theory_ref,
|
wenzelm@16601
|
190 |
t: term,
|
wenzelm@16601
|
191 |
T: typ,
|
wenzelm@16601
|
192 |
maxidx: int,
|
wenzelm@39935
|
193 |
sorts: sort Ord_List.T}
|
wenzelm@32590
|
194 |
with
|
wenzelm@250
|
195 |
|
wenzelm@22584
|
196 |
exception CTERM of string * cterm list;
|
wenzelm@16679
|
197 |
|
wenzelm@26631
|
198 |
fun rep_cterm (Cterm args) = args;
|
lcp@229
|
199 |
|
wenzelm@16601
|
200 |
fun crep_cterm (Cterm {thy_ref, t, T, maxidx, sorts}) =
|
wenzelm@26631
|
201 |
{thy_ref = thy_ref, t = t, maxidx = maxidx, sorts = sorts,
|
wenzelm@26631
|
202 |
T = Ctyp {thy_ref = thy_ref, T = T, maxidx = maxidx, sorts = sorts}};
|
wenzelm@4288
|
203 |
|
wenzelm@16425
|
204 |
fun theory_of_cterm (Cterm {thy_ref, ...}) = Theory.deref thy_ref;
|
wenzelm@250
|
205 |
fun term_of (Cterm {t, ...}) = t;
|
lcp@229
|
206 |
|
wenzelm@20512
|
207 |
fun ctyp_of_term (Cterm {thy_ref, T, maxidx, sorts, ...}) =
|
wenzelm@20512
|
208 |
Ctyp {thy_ref = thy_ref, T = T, maxidx = maxidx, sorts = sorts};
|
paulson@2671
|
209 |
|
wenzelm@16425
|
210 |
fun cterm_of thy tm =
|
wenzelm@16601
|
211 |
let
|
wenzelm@18969
|
212 |
val (t, T, maxidx) = Sign.certify_term thy tm;
|
wenzelm@26640
|
213 |
val sorts = Sorts.insert_term t [];
|
wenzelm@24143
|
214 |
in Cterm {thy_ref = Theory.check_thy thy, t = t, T = T, maxidx = maxidx, sorts = sorts} end;
|
wenzelm@250
|
215 |
|
wenzelm@32791
|
216 |
fun merge_thys0 (Cterm {thy_ref = r1, ...}) (Cterm {thy_ref = r2, ...}) =
|
wenzelm@23601
|
217 |
Theory.merge_refs (r1, r2);
|
wenzelm@16656
|
218 |
|
wenzelm@20580
|
219 |
|
wenzelm@22909
|
220 |
(* destructors *)
|
wenzelm@22909
|
221 |
|
wenzelm@32791
|
222 |
fun dest_comb (Cterm {t = c $ a, T, thy_ref, maxidx, sorts}) =
|
wenzelm@22909
|
223 |
let val A = Term.argument_type_of c 0 in
|
wenzelm@22909
|
224 |
(Cterm {t = c, T = A --> T, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts},
|
wenzelm@22909
|
225 |
Cterm {t = a, T = A, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts})
|
clasohm@1493
|
226 |
end
|
wenzelm@22584
|
227 |
| dest_comb ct = raise CTERM ("dest_comb", [ct]);
|
clasohm@1493
|
228 |
|
wenzelm@32791
|
229 |
fun dest_fun (Cterm {t = c $ _, T, thy_ref, maxidx, sorts}) =
|
wenzelm@22909
|
230 |
let val A = Term.argument_type_of c 0
|
wenzelm@22909
|
231 |
in Cterm {t = c, T = A --> T, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts} end
|
wenzelm@22909
|
232 |
| dest_fun ct = raise CTERM ("dest_fun", [ct]);
|
wenzelm@22909
|
233 |
|
wenzelm@32791
|
234 |
fun dest_arg (Cterm {t = c $ a, T = _, thy_ref, maxidx, sorts}) =
|
wenzelm@22909
|
235 |
let val A = Term.argument_type_of c 0
|
wenzelm@22909
|
236 |
in Cterm {t = a, T = A, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts} end
|
wenzelm@22584
|
237 |
| dest_arg ct = raise CTERM ("dest_arg", [ct]);
|
wenzelm@20580
|
238 |
|
wenzelm@22909
|
239 |
|
wenzelm@32791
|
240 |
fun dest_fun2 (Cterm {t = c $ _ $ _, T, thy_ref, maxidx, sorts}) =
|
wenzelm@22909
|
241 |
let
|
wenzelm@22909
|
242 |
val A = Term.argument_type_of c 0;
|
wenzelm@22909
|
243 |
val B = Term.argument_type_of c 1;
|
wenzelm@22909
|
244 |
in Cterm {t = c, T = A --> B --> T, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts} end
|
wenzelm@22909
|
245 |
| dest_fun2 ct = raise CTERM ("dest_fun2", [ct]);
|
wenzelm@22909
|
246 |
|
wenzelm@22909
|
247 |
fun dest_arg1 (Cterm {t = c $ a $ _, T = _, thy_ref, maxidx, sorts}) =
|
wenzelm@22909
|
248 |
let val A = Term.argument_type_of c 0
|
wenzelm@22909
|
249 |
in Cterm {t = a, T = A, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts} end
|
wenzelm@22909
|
250 |
| dest_arg1 ct = raise CTERM ("dest_arg1", [ct]);
|
wenzelm@20673
|
251 |
|
wenzelm@32791
|
252 |
fun dest_abs a (Cterm {t = Abs (x, T, t), T = Type ("fun", [_, U]), thy_ref, maxidx, sorts}) =
|
wenzelm@18944
|
253 |
let val (y', t') = Term.dest_abs (the_default x a, T, t) in
|
wenzelm@16679
|
254 |
(Cterm {t = Free (y', T), T = T, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts},
|
wenzelm@16679
|
255 |
Cterm {t = t', T = U, thy_ref = thy_ref, maxidx = maxidx, sorts = sorts})
|
clasohm@1493
|
256 |
end
|
wenzelm@22584
|
257 |
| dest_abs _ ct = raise CTERM ("dest_abs", [ct]);
|
clasohm@1493
|
258 |
|
wenzelm@22909
|
259 |
|
wenzelm@22909
|
260 |
(* constructors *)
|
wenzelm@22909
|
261 |
|
wenzelm@16601
|
262 |
fun capply
|
wenzelm@16656
|
263 |
(cf as Cterm {t = f, T = Type ("fun", [dty, rty]), maxidx = maxidx1, sorts = sorts1, ...})
|
wenzelm@16656
|
264 |
(cx as Cterm {t = x, T, maxidx = maxidx2, sorts = sorts2, ...}) =
|
wenzelm@16601
|
265 |
if T = dty then
|
wenzelm@16656
|
266 |
Cterm {thy_ref = merge_thys0 cf cx,
|
wenzelm@16656
|
267 |
t = f $ x,
|
wenzelm@16656
|
268 |
T = rty,
|
wenzelm@16656
|
269 |
maxidx = Int.max (maxidx1, maxidx2),
|
wenzelm@16601
|
270 |
sorts = Sorts.union sorts1 sorts2}
|
wenzelm@22584
|
271 |
else raise CTERM ("capply: types don't agree", [cf, cx])
|
wenzelm@22584
|
272 |
| capply cf cx = raise CTERM ("capply: first arg is not a function", [cf, cx]);
|
lcp@229
|
273 |
|
wenzelm@32204
|
274 |
fun cabs_name
|
wenzelm@32204
|
275 |
(x, ct1 as Cterm {t = t1, T = T1, maxidx = maxidx1, sorts = sorts1, ...})
|
wenzelm@16656
|
276 |
(ct2 as Cterm {t = t2, T = T2, maxidx = maxidx2, sorts = sorts2, ...}) =
|
wenzelm@32204
|
277 |
let val t = Term.lambda_name (x, t1) t2 in
|
wenzelm@16656
|
278 |
Cterm {thy_ref = merge_thys0 ct1 ct2,
|
wenzelm@16656
|
279 |
t = t, T = T1 --> T2,
|
wenzelm@16656
|
280 |
maxidx = Int.max (maxidx1, maxidx2),
|
wenzelm@16656
|
281 |
sorts = Sorts.union sorts1 sorts2}
|
wenzelm@16601
|
282 |
end;
|
wenzelm@250
|
283 |
|
wenzelm@32204
|
284 |
fun cabs t u = cabs_name ("", t) u;
|
wenzelm@32204
|
285 |
|
wenzelm@20580
|
286 |
|
wenzelm@22909
|
287 |
(* indexes *)
|
wenzelm@22909
|
288 |
|
wenzelm@20580
|
289 |
fun adjust_maxidx_cterm i (ct as Cterm {thy_ref, t, T, maxidx, sorts}) =
|
wenzelm@20580
|
290 |
if maxidx = i then ct
|
wenzelm@20580
|
291 |
else if maxidx < i then
|
wenzelm@20580
|
292 |
Cterm {maxidx = i, thy_ref = thy_ref, t = t, T = T, sorts = sorts}
|
wenzelm@20580
|
293 |
else
|
wenzelm@20580
|
294 |
Cterm {maxidx = Int.max (maxidx_of_term t, i), thy_ref = thy_ref, t = t, T = T, sorts = sorts};
|
wenzelm@20580
|
295 |
|
wenzelm@22909
|
296 |
fun incr_indexes_cterm i (ct as Cterm {thy_ref, t, T, maxidx, sorts}) =
|
wenzelm@22909
|
297 |
if i < 0 then raise CTERM ("negative increment", [ct])
|
wenzelm@22909
|
298 |
else if i = 0 then ct
|
wenzelm@22909
|
299 |
else Cterm {thy_ref = thy_ref, t = Logic.incr_indexes ([], i) t,
|
wenzelm@22909
|
300 |
T = Logic.incr_tvar i T, maxidx = maxidx + i, sorts = sorts};
|
wenzelm@22909
|
301 |
|
wenzelm@22909
|
302 |
|
wenzelm@22909
|
303 |
(* matching *)
|
wenzelm@22909
|
304 |
|
wenzelm@22909
|
305 |
local
|
wenzelm@22909
|
306 |
|
wenzelm@22909
|
307 |
fun gen_match match
|
wenzelm@20512
|
308 |
(ct1 as Cterm {t = t1, sorts = sorts1, ...},
|
wenzelm@20815
|
309 |
ct2 as Cterm {t = t2, sorts = sorts2, maxidx = maxidx2, ...}) =
|
berghofe@10416
|
310 |
let
|
wenzelm@24143
|
311 |
val thy = Theory.deref (merge_thys0 ct1 ct2);
|
wenzelm@24143
|
312 |
val (Tinsts, tinsts) = match thy (t1, t2) (Vartab.empty, Vartab.empty);
|
wenzelm@16601
|
313 |
val sorts = Sorts.union sorts1 sorts2;
|
wenzelm@20512
|
314 |
fun mk_cTinst ((a, i), (S, T)) =
|
wenzelm@24143
|
315 |
(Ctyp {T = TVar ((a, i), S), thy_ref = Theory.check_thy thy, maxidx = i, sorts = sorts},
|
wenzelm@24143
|
316 |
Ctyp {T = T, thy_ref = Theory.check_thy thy, maxidx = maxidx2, sorts = sorts});
|
wenzelm@20512
|
317 |
fun mk_ctinst ((x, i), (T, t)) =
|
wenzelm@32046
|
318 |
let val T = Envir.subst_type Tinsts T in
|
wenzelm@24143
|
319 |
(Cterm {t = Var ((x, i), T), T = T, thy_ref = Theory.check_thy thy,
|
wenzelm@24143
|
320 |
maxidx = i, sorts = sorts},
|
wenzelm@24143
|
321 |
Cterm {t = t, T = T, thy_ref = Theory.check_thy thy, maxidx = maxidx2, sorts = sorts})
|
berghofe@10416
|
322 |
end;
|
wenzelm@16656
|
323 |
in (Vartab.fold (cons o mk_cTinst) Tinsts [], Vartab.fold (cons o mk_ctinst) tinsts []) end;
|
berghofe@10416
|
324 |
|
wenzelm@22909
|
325 |
in
|
berghofe@10416
|
326 |
|
wenzelm@22909
|
327 |
val match = gen_match Pattern.match;
|
wenzelm@22909
|
328 |
val first_order_match = gen_match Pattern.first_order_match;
|
wenzelm@22909
|
329 |
|
wenzelm@22909
|
330 |
end;
|
berghofe@10416
|
331 |
|
wenzelm@2509
|
332 |
|
wenzelm@2509
|
333 |
|
wenzelm@28321
|
334 |
(*** Derivations and Theorems ***)
|
lcp@229
|
335 |
|
wenzelm@32590
|
336 |
abstype thm = Thm of
|
wenzelm@40370
|
337 |
deriv * (*derivation*)
|
wenzelm@40370
|
338 |
{thy_ref: theory_ref, (*dynamic reference to theory*)
|
wenzelm@40370
|
339 |
tags: Properties.T, (*additional annotations/comments*)
|
wenzelm@40370
|
340 |
maxidx: int, (*maximum index of any Var or TVar*)
|
wenzelm@40370
|
341 |
shyps: sort Ord_List.T, (*sort hypotheses*)
|
wenzelm@40370
|
342 |
hyps: term Ord_List.T, (*hypotheses*)
|
wenzelm@40370
|
343 |
tpairs: (term * term) list, (*flex-flex pairs*)
|
wenzelm@40370
|
344 |
prop: term} (*conclusion*)
|
wenzelm@28624
|
345 |
and deriv = Deriv of
|
wenzelm@39935
|
346 |
{promises: (serial * thm future) Ord_List.T,
|
wenzelm@37309
|
347 |
body: Proofterm.proof_body}
|
wenzelm@32590
|
348 |
with
|
clasohm@0
|
349 |
|
wenzelm@23601
|
350 |
type conv = cterm -> thm;
|
wenzelm@23601
|
351 |
|
wenzelm@16725
|
352 |
(*errors involving theorems*)
|
wenzelm@16725
|
353 |
exception THM of string * int * thm list;
|
berghofe@13658
|
354 |
|
wenzelm@28321
|
355 |
fun rep_thm (Thm (_, args)) = args;
|
clasohm@0
|
356 |
|
wenzelm@28321
|
357 |
fun crep_thm (Thm (_, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
|
wenzelm@26631
|
358 |
let fun cterm max t = Cterm {thy_ref = thy_ref, t = t, T = propT, maxidx = max, sorts = shyps} in
|
wenzelm@28321
|
359 |
{thy_ref = thy_ref, tags = tags, maxidx = maxidx, shyps = shyps,
|
wenzelm@16425
|
360 |
hyps = map (cterm ~1) hyps,
|
wenzelm@16425
|
361 |
tpairs = map (pairself (cterm maxidx)) tpairs,
|
wenzelm@16425
|
362 |
prop = cterm maxidx prop}
|
clasohm@1517
|
363 |
end;
|
clasohm@1517
|
364 |
|
wenzelm@31947
|
365 |
fun fold_terms f (Thm (_, {tpairs, prop, hyps, ...})) =
|
wenzelm@31947
|
366 |
fold (fn (t, u) => f t #> f u) tpairs #> f prop #> fold f hyps;
|
wenzelm@31947
|
367 |
|
wenzelm@16725
|
368 |
fun terms_of_tpairs tpairs = fold_rev (fn (t, u) => cons t o cons u) tpairs [];
|
wenzelm@16725
|
369 |
|
wenzelm@16725
|
370 |
fun eq_tpairs ((t, u), (t', u')) = t aconv t' andalso u aconv u';
|
wenzelm@18944
|
371 |
fun union_tpairs ts us = Library.merge eq_tpairs (ts, us);
|
wenzelm@16884
|
372 |
val maxidx_tpairs = fold (fn (t, u) => Term.maxidx_term t #> Term.maxidx_term u);
|
wenzelm@16725
|
373 |
|
wenzelm@16725
|
374 |
fun attach_tpairs tpairs prop =
|
wenzelm@16725
|
375 |
Logic.list_implies (map Logic.mk_equals tpairs, prop);
|
wenzelm@16725
|
376 |
|
wenzelm@28321
|
377 |
fun full_prop_of (Thm (_, {tpairs, prop, ...})) = attach_tpairs tpairs prop;
|
wenzelm@16945
|
378 |
|
wenzelm@39935
|
379 |
val union_hyps = Ord_List.union Term_Ord.fast_term_ord;
|
wenzelm@39935
|
380 |
val insert_hyps = Ord_List.insert Term_Ord.fast_term_ord;
|
wenzelm@39935
|
381 |
val remove_hyps = Ord_List.remove Term_Ord.fast_term_ord;
|
wenzelm@22365
|
382 |
|
wenzelm@16945
|
383 |
|
wenzelm@24143
|
384 |
(* merge theories of cterms/thms -- trivial absorption only *)
|
wenzelm@16945
|
385 |
|
wenzelm@32791
|
386 |
fun merge_thys1 (Cterm {thy_ref = r1, ...}) (Thm (_, {thy_ref = r2, ...})) =
|
wenzelm@23601
|
387 |
Theory.merge_refs (r1, r2);
|
wenzelm@16945
|
388 |
|
wenzelm@32791
|
389 |
fun merge_thys2 (Thm (_, {thy_ref = r1, ...})) (Thm (_, {thy_ref = r2, ...})) =
|
wenzelm@23601
|
390 |
Theory.merge_refs (r1, r2);
|
wenzelm@16945
|
391 |
|
clasohm@0
|
392 |
|
wenzelm@22365
|
393 |
(* basic components *)
|
wenzelm@16135
|
394 |
|
wenzelm@28321
|
395 |
val theory_of_thm = Theory.deref o #thy_ref o rep_thm;
|
wenzelm@28321
|
396 |
val maxidx_of = #maxidx o rep_thm;
|
wenzelm@19910
|
397 |
fun maxidx_thm th i = Int.max (maxidx_of th, i);
|
wenzelm@28321
|
398 |
val hyps_of = #hyps o rep_thm;
|
wenzelm@28321
|
399 |
val prop_of = #prop o rep_thm;
|
wenzelm@28321
|
400 |
val tpairs_of = #tpairs o rep_thm;
|
wenzelm@387
|
401 |
|
wenzelm@16601
|
402 |
val concl_of = Logic.strip_imp_concl o prop_of;
|
wenzelm@16601
|
403 |
val prems_of = Logic.strip_imp_prems o prop_of;
|
wenzelm@21576
|
404 |
val nprems_of = Logic.count_prems o prop_of;
|
wenzelm@19305
|
405 |
fun no_prems th = nprems_of th = 0;
|
wenzelm@16601
|
406 |
|
wenzelm@16601
|
407 |
fun major_prem_of th =
|
wenzelm@16601
|
408 |
(case prems_of th of
|
wenzelm@16601
|
409 |
prem :: _ => Logic.strip_assums_concl prem
|
wenzelm@16601
|
410 |
| [] => raise THM ("major_prem_of: rule with no premises", 0, [th]));
|
wenzelm@16601
|
411 |
|
wenzelm@16601
|
412 |
(*the statement of any thm is a cterm*)
|
wenzelm@28321
|
413 |
fun cprop_of (Thm (_, {thy_ref, maxidx, shyps, prop, ...})) =
|
wenzelm@16601
|
414 |
Cterm {thy_ref = thy_ref, maxidx = maxidx, T = propT, t = prop, sorts = shyps};
|
wenzelm@16601
|
415 |
|
wenzelm@28321
|
416 |
fun cprem_of (th as Thm (_, {thy_ref, maxidx, shyps, prop, ...})) i =
|
wenzelm@18035
|
417 |
Cterm {thy_ref = thy_ref, maxidx = maxidx, T = propT, sorts = shyps,
|
wenzelm@18145
|
418 |
t = Logic.nth_prem (i, prop) handle TERM _ => raise THM ("cprem_of", i, [th])};
|
wenzelm@18035
|
419 |
|
wenzelm@16656
|
420 |
(*explicit transfer to a super theory*)
|
wenzelm@16425
|
421 |
fun transfer thy' thm =
|
wenzelm@3895
|
422 |
let
|
wenzelm@28321
|
423 |
val Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop}) = thm;
|
wenzelm@16425
|
424 |
val thy = Theory.deref thy_ref;
|
wenzelm@26665
|
425 |
val _ = Theory.subthy (thy, thy') orelse raise THM ("transfer: not a super theory", 0, [thm]);
|
wenzelm@26665
|
426 |
val is_eq = Theory.eq_thy (thy, thy');
|
wenzelm@24143
|
427 |
val _ = Theory.check_thy thy;
|
wenzelm@3895
|
428 |
in
|
wenzelm@24143
|
429 |
if is_eq then thm
|
wenzelm@16945
|
430 |
else
|
wenzelm@28321
|
431 |
Thm (der,
|
wenzelm@28321
|
432 |
{thy_ref = Theory.check_thy thy',
|
wenzelm@21646
|
433 |
tags = tags,
|
wenzelm@16945
|
434 |
maxidx = maxidx,
|
wenzelm@16945
|
435 |
shyps = shyps,
|
wenzelm@16945
|
436 |
hyps = hyps,
|
wenzelm@16945
|
437 |
tpairs = tpairs,
|
wenzelm@28321
|
438 |
prop = prop})
|
wenzelm@3895
|
439 |
end;
|
wenzelm@387
|
440 |
|
wenzelm@16945
|
441 |
(*explicit weakening: maps |- B to A |- B*)
|
wenzelm@16945
|
442 |
fun weaken raw_ct th =
|
wenzelm@16945
|
443 |
let
|
wenzelm@20261
|
444 |
val ct as Cterm {t = A, T, sorts, maxidx = maxidxA, ...} = adjust_maxidx_cterm ~1 raw_ct;
|
wenzelm@28321
|
445 |
val Thm (der, {tags, maxidx, shyps, hyps, tpairs, prop, ...}) = th;
|
wenzelm@16945
|
446 |
in
|
wenzelm@16945
|
447 |
if T <> propT then
|
wenzelm@16945
|
448 |
raise THM ("weaken: assumptions must have type prop", 0, [])
|
wenzelm@16945
|
449 |
else if maxidxA <> ~1 then
|
wenzelm@16945
|
450 |
raise THM ("weaken: assumptions may not contain schematic variables", maxidxA, [])
|
wenzelm@16945
|
451 |
else
|
wenzelm@28321
|
452 |
Thm (der,
|
wenzelm@28321
|
453 |
{thy_ref = merge_thys1 ct th,
|
wenzelm@21646
|
454 |
tags = tags,
|
wenzelm@16945
|
455 |
maxidx = maxidx,
|
wenzelm@16945
|
456 |
shyps = Sorts.union sorts shyps,
|
wenzelm@28354
|
457 |
hyps = insert_hyps A hyps,
|
wenzelm@16945
|
458 |
tpairs = tpairs,
|
wenzelm@28321
|
459 |
prop = prop})
|
wenzelm@16945
|
460 |
end;
|
wenzelm@16656
|
461 |
|
wenzelm@28624
|
462 |
fun weaken_sorts raw_sorts ct =
|
wenzelm@28624
|
463 |
let
|
wenzelm@28624
|
464 |
val Cterm {thy_ref, t, T, maxidx, sorts} = ct;
|
wenzelm@28624
|
465 |
val thy = Theory.deref thy_ref;
|
wenzelm@28624
|
466 |
val more_sorts = Sorts.make (map (Sign.certify_sort thy) raw_sorts);
|
wenzelm@28624
|
467 |
val sorts' = Sorts.union sorts more_sorts;
|
wenzelm@28624
|
468 |
in Cterm {thy_ref = Theory.check_thy thy, t = t, T = T, maxidx = maxidx, sorts = sorts'} end;
|
wenzelm@28624
|
469 |
|
wenzelm@16656
|
470 |
(*dangling sort constraints of a thm*)
|
wenzelm@31947
|
471 |
fun extra_shyps (th as Thm (_, {shyps, ...})) =
|
wenzelm@31947
|
472 |
Sorts.subtract (fold_terms Sorts.insert_term th []) shyps;
|
wenzelm@28321
|
473 |
|
wenzelm@28321
|
474 |
|
wenzelm@28321
|
475 |
|
wenzelm@32730
|
476 |
(** derivations and promised proofs **)
|
wenzelm@28321
|
477 |
|
wenzelm@32075
|
478 |
fun make_deriv promises oracles thms proof =
|
wenzelm@32075
|
479 |
Deriv {promises = promises, body = PBody {oracles = oracles, thms = thms, proof = proof}};
|
wenzelm@28321
|
480 |
|
wenzelm@37309
|
481 |
val empty_deriv = make_deriv [] [] [] Proofterm.MinProof;
|
wenzelm@28321
|
482 |
|
wenzelm@28321
|
483 |
|
wenzelm@28354
|
484 |
(* inference rules *)
|
wenzelm@28330
|
485 |
|
wenzelm@28378
|
486 |
fun promise_ord ((i, _), (j, _)) = int_ord (j, i);
|
wenzelm@28330
|
487 |
|
wenzelm@28321
|
488 |
fun deriv_rule2 f
|
wenzelm@32075
|
489 |
(Deriv {promises = ps1, body = PBody {oracles = oras1, thms = thms1, proof = prf1}})
|
wenzelm@32075
|
490 |
(Deriv {promises = ps2, body = PBody {oracles = oras2, thms = thms2, proof = prf2}}) =
|
wenzelm@28321
|
491 |
let
|
wenzelm@39935
|
492 |
val ps = Ord_List.union promise_ord ps1 ps2;
|
wenzelm@37309
|
493 |
val oras = Proofterm.merge_oracles oras1 oras2;
|
wenzelm@37309
|
494 |
val thms = Proofterm.merge_thms thms1 thms2;
|
wenzelm@28321
|
495 |
val prf =
|
wenzelm@37309
|
496 |
(case ! Proofterm.proofs of
|
wenzelm@28321
|
497 |
2 => f prf1 prf2
|
wenzelm@28804
|
498 |
| 1 => MinProof
|
wenzelm@28804
|
499 |
| 0 => MinProof
|
wenzelm@28321
|
500 |
| i => error ("Illegal level of detail for proof objects: " ^ string_of_int i));
|
wenzelm@32075
|
501 |
in make_deriv ps oras thms prf end;
|
wenzelm@28321
|
502 |
|
wenzelm@28321
|
503 |
fun deriv_rule1 f = deriv_rule2 (K f) empty_deriv;
|
wenzelm@32075
|
504 |
fun deriv_rule0 prf = deriv_rule1 I (make_deriv [] [] [] prf);
|
wenzelm@28321
|
505 |
|
wenzelm@36644
|
506 |
fun deriv_rule_unconditional f (Deriv {promises, body = PBody {oracles, thms, proof}}) =
|
wenzelm@36644
|
507 |
make_deriv promises oracles thms (f proof);
|
wenzelm@36644
|
508 |
|
wenzelm@1238
|
509 |
|
wenzelm@32730
|
510 |
(* fulfilled proofs *)
|
wenzelm@32730
|
511 |
|
wenzelm@32730
|
512 |
fun raw_body (Thm (Deriv {body, ...}, _)) = body;
|
wenzelm@32730
|
513 |
|
wenzelm@32730
|
514 |
fun fulfill_body (Thm (Deriv {promises, body}, {thy_ref, ...})) =
|
wenzelm@37309
|
515 |
Proofterm.fulfill_norm_proof (Theory.deref thy_ref)
|
wenzelm@32730
|
516 |
(map #1 promises ~~ fulfill_bodies (map #2 promises)) body
|
wenzelm@32730
|
517 |
and fulfill_bodies futures = map fulfill_body (Exn.release_all (Future.join_results futures));
|
wenzelm@32730
|
518 |
|
wenzelm@37309
|
519 |
val join_proofs = Proofterm.join_bodies o map fulfill_body;
|
wenzelm@32730
|
520 |
|
wenzelm@37309
|
521 |
fun proof_body_of thm = (Proofterm.join_bodies [raw_body thm]; fulfill_body thm);
|
wenzelm@37309
|
522 |
val proof_of = Proofterm.proof_of o proof_body_of;
|
wenzelm@32730
|
523 |
|
wenzelm@32730
|
524 |
|
wenzelm@32730
|
525 |
(* derivation status *)
|
wenzelm@32730
|
526 |
|
wenzelm@32730
|
527 |
fun status_of (Thm (Deriv {promises, body}, _)) =
|
wenzelm@32730
|
528 |
let
|
wenzelm@32730
|
529 |
val ps = map (Future.peek o snd) promises;
|
wenzelm@32730
|
530 |
val bodies = body ::
|
wenzelm@32730
|
531 |
map_filter (fn SOME (Exn.Result th) => SOME (raw_body th) | _ => NONE) ps;
|
wenzelm@37309
|
532 |
val {oracle, unfinished, failed} = Proofterm.status_of bodies;
|
wenzelm@32730
|
533 |
in
|
wenzelm@32730
|
534 |
{oracle = oracle,
|
wenzelm@32730
|
535 |
unfinished = unfinished orelse exists is_none ps,
|
wenzelm@32730
|
536 |
failed = failed orelse exists (fn SOME (Exn.Exn _) => true | _ => false) ps}
|
wenzelm@32730
|
537 |
end;
|
wenzelm@32730
|
538 |
|
wenzelm@32730
|
539 |
|
wenzelm@32730
|
540 |
(* future rule *)
|
wenzelm@32730
|
541 |
|
wenzelm@36636
|
542 |
fun future_result i orig_thy orig_shyps orig_prop thm =
|
wenzelm@32730
|
543 |
let
|
wenzelm@36636
|
544 |
fun err msg = raise THM ("future_result: " ^ msg, 0, [thm]);
|
wenzelm@36636
|
545 |
val Thm (Deriv {promises, ...}, {thy_ref, shyps, hyps, tpairs, prop, ...}) = thm;
|
wenzelm@36636
|
546 |
|
wenzelm@36636
|
547 |
val _ = Theory.eq_thy (Theory.deref thy_ref, orig_thy) orelse err "bad theory";
|
wenzelm@32730
|
548 |
val _ = Theory.check_thy orig_thy;
|
wenzelm@32730
|
549 |
val _ = prop aconv orig_prop orelse err "bad prop";
|
wenzelm@32730
|
550 |
val _ = null tpairs orelse err "bad tpairs";
|
wenzelm@32730
|
551 |
val _ = null hyps orelse err "bad hyps";
|
wenzelm@32730
|
552 |
val _ = Sorts.subset (shyps, orig_shyps) orelse err "bad shyps";
|
wenzelm@32730
|
553 |
val _ = forall (fn (j, _) => i <> j) promises orelse err "bad dependencies";
|
wenzelm@32730
|
554 |
val _ = fulfill_bodies (map #2 promises);
|
wenzelm@32730
|
555 |
in thm end;
|
wenzelm@32730
|
556 |
|
wenzelm@32730
|
557 |
fun future future_thm ct =
|
wenzelm@32730
|
558 |
let
|
wenzelm@32730
|
559 |
val Cterm {thy_ref = thy_ref, t = prop, T, maxidx, sorts} = ct;
|
wenzelm@32730
|
560 |
val thy = Context.reject_draft (Theory.deref thy_ref);
|
wenzelm@32730
|
561 |
val _ = T <> propT andalso raise CTERM ("future: prop expected", [ct]);
|
wenzelm@32730
|
562 |
|
wenzelm@32730
|
563 |
val i = serial ();
|
wenzelm@32730
|
564 |
val future = future_thm |> Future.map (future_result i thy sorts prop);
|
wenzelm@32730
|
565 |
in
|
wenzelm@37309
|
566 |
Thm (make_deriv [(i, future)] [] [] (Proofterm.promise_proof thy i prop),
|
wenzelm@32730
|
567 |
{thy_ref = thy_ref,
|
wenzelm@32730
|
568 |
tags = [],
|
wenzelm@32730
|
569 |
maxidx = maxidx,
|
wenzelm@32730
|
570 |
shyps = sorts,
|
wenzelm@32730
|
571 |
hyps = [],
|
wenzelm@32730
|
572 |
tpairs = [],
|
wenzelm@32730
|
573 |
prop = prop})
|
wenzelm@32730
|
574 |
end;
|
wenzelm@32730
|
575 |
|
wenzelm@32730
|
576 |
|
wenzelm@32730
|
577 |
(* closed derivations with official name *)
|
wenzelm@32730
|
578 |
|
wenzelm@42573
|
579 |
(*non-deterministic, depends on unknown promises*)
|
wenzelm@37297
|
580 |
fun derivation_name (Thm (Deriv {body, ...}, {shyps, hyps, prop, ...})) =
|
wenzelm@37309
|
581 |
Proofterm.get_name shyps hyps prop (Proofterm.proof_of body);
|
wenzelm@32730
|
582 |
|
wenzelm@36753
|
583 |
fun name_derivation name (thm as Thm (der, args)) =
|
wenzelm@32730
|
584 |
let
|
wenzelm@32730
|
585 |
val Deriv {promises, body} = der;
|
wenzelm@36930
|
586 |
val {thy_ref, shyps, hyps, prop, tpairs, ...} = args;
|
wenzelm@32730
|
587 |
val _ = null tpairs orelse raise THM ("put_name: unsolved flex-flex constraints", 0, [thm]);
|
wenzelm@32730
|
588 |
|
wenzelm@42574
|
589 |
val ps = map (apsnd (Future.map fulfill_body)) promises;
|
wenzelm@32730
|
590 |
val thy = Theory.deref thy_ref;
|
wenzelm@37309
|
591 |
val (pthm, proof) = Proofterm.thm_proof thy name shyps hyps prop ps body;
|
wenzelm@32730
|
592 |
val der' = make_deriv [] [] [pthm] proof;
|
wenzelm@32730
|
593 |
val _ = Theory.check_thy thy;
|
wenzelm@32730
|
594 |
in Thm (der', args) end;
|
wenzelm@32730
|
595 |
|
wenzelm@32730
|
596 |
|
wenzelm@1238
|
597 |
|
paulson@1529
|
598 |
(** Axioms **)
|
wenzelm@387
|
599 |
|
wenzelm@28675
|
600 |
fun axiom theory name =
|
wenzelm@387
|
601 |
let
|
wenzelm@16425
|
602 |
fun get_ax thy =
|
wenzelm@22685
|
603 |
Symtab.lookup (Theory.axiom_table thy) name
|
wenzelm@16601
|
604 |
|> Option.map (fn prop =>
|
wenzelm@24143
|
605 |
let
|
wenzelm@37309
|
606 |
val der = deriv_rule0 (Proofterm.axm_proof name prop);
|
wenzelm@24143
|
607 |
val maxidx = maxidx_of_term prop;
|
wenzelm@26640
|
608 |
val shyps = Sorts.insert_term prop [];
|
wenzelm@24143
|
609 |
in
|
wenzelm@28321
|
610 |
Thm (der, {thy_ref = Theory.check_thy thy, tags = [],
|
wenzelm@28321
|
611 |
maxidx = maxidx, shyps = shyps, hyps = [], tpairs = [], prop = prop})
|
wenzelm@24143
|
612 |
end);
|
wenzelm@387
|
613 |
in
|
wenzelm@43304
|
614 |
(case get_first get_ax (Theory.nodes_of theory) of
|
skalberg@15531
|
615 |
SOME thm => thm
|
skalberg@15531
|
616 |
| NONE => raise THEORY ("No axiom " ^ quote name, [theory]))
|
wenzelm@387
|
617 |
end;
|
wenzelm@387
|
618 |
|
wenzelm@776
|
619 |
(*return additional axioms of this theory node*)
|
wenzelm@776
|
620 |
fun axioms_of thy =
|
wenzelm@28675
|
621 |
map (fn s => (s, axiom thy s)) (Symtab.keys (Theory.axiom_table thy));
|
wenzelm@776
|
622 |
|
wenzelm@6089
|
623 |
|
wenzelm@28804
|
624 |
(* tags *)
|
wenzelm@6089
|
625 |
|
wenzelm@21646
|
626 |
val get_tags = #tags o rep_thm;
|
wenzelm@6089
|
627 |
|
wenzelm@28321
|
628 |
fun map_tags f (Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
|
wenzelm@28321
|
629 |
Thm (der, {thy_ref = thy_ref, tags = f tags, maxidx = maxidx,
|
wenzelm@28321
|
630 |
shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop});
|
wenzelm@387
|
631 |
|
clasohm@922
|
632 |
|
wenzelm@28321
|
633 |
fun norm_proof (Thm (der, args as {thy_ref, ...})) =
|
wenzelm@24143
|
634 |
let
|
wenzelm@24143
|
635 |
val thy = Theory.deref thy_ref;
|
wenzelm@37309
|
636 |
val der' = deriv_rule1 (Proofterm.rew_proof thy) der;
|
wenzelm@28321
|
637 |
val _ = Theory.check_thy thy;
|
wenzelm@28321
|
638 |
in Thm (der', args) end;
|
berghofe@23781
|
639 |
|
wenzelm@28321
|
640 |
fun adjust_maxidx_thm i (th as Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
|
wenzelm@20261
|
641 |
if maxidx = i then th
|
wenzelm@20261
|
642 |
else if maxidx < i then
|
wenzelm@28321
|
643 |
Thm (der, {maxidx = i, thy_ref = thy_ref, tags = tags, shyps = shyps,
|
wenzelm@28321
|
644 |
hyps = hyps, tpairs = tpairs, prop = prop})
|
wenzelm@20261
|
645 |
else
|
wenzelm@28321
|
646 |
Thm (der, {maxidx = Int.max (maxidx_tpairs tpairs (maxidx_of_term prop), i), thy_ref = thy_ref,
|
wenzelm@28321
|
647 |
tags = tags, shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop});
|
wenzelm@387
|
648 |
|
wenzelm@387
|
649 |
|
wenzelm@2509
|
650 |
|
paulson@1529
|
651 |
(*** Meta rules ***)
|
clasohm@0
|
652 |
|
wenzelm@16601
|
653 |
(** primitive rules **)
|
wenzelm@1220
|
654 |
|
wenzelm@16656
|
655 |
(*The assumption rule A |- A*)
|
wenzelm@16601
|
656 |
fun assume raw_ct =
|
wenzelm@20261
|
657 |
let val Cterm {thy_ref, t = prop, T, maxidx, sorts} = adjust_maxidx_cterm ~1 raw_ct in
|
wenzelm@16601
|
658 |
if T <> propT then
|
mengj@19230
|
659 |
raise THM ("assume: prop", 0, [])
|
wenzelm@16601
|
660 |
else if maxidx <> ~1 then
|
mengj@19230
|
661 |
raise THM ("assume: variables", maxidx, [])
|
wenzelm@37309
|
662 |
else Thm (deriv_rule0 (Proofterm.Hyp prop),
|
wenzelm@28321
|
663 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
664 |
tags = [],
|
wenzelm@16601
|
665 |
maxidx = ~1,
|
wenzelm@16601
|
666 |
shyps = sorts,
|
wenzelm@16601
|
667 |
hyps = [prop],
|
wenzelm@16601
|
668 |
tpairs = [],
|
wenzelm@28321
|
669 |
prop = prop})
|
clasohm@0
|
670 |
end;
|
clasohm@0
|
671 |
|
wenzelm@1220
|
672 |
(*Implication introduction
|
wenzelm@3529
|
673 |
[A]
|
wenzelm@3529
|
674 |
:
|
wenzelm@3529
|
675 |
B
|
wenzelm@1220
|
676 |
-------
|
wenzelm@1220
|
677 |
A ==> B
|
wenzelm@1220
|
678 |
*)
|
wenzelm@16601
|
679 |
fun implies_intr
|
wenzelm@16679
|
680 |
(ct as Cterm {t = A, T, maxidx = maxidxA, sorts, ...})
|
wenzelm@28321
|
681 |
(th as Thm (der, {maxidx, hyps, shyps, tpairs, prop, ...})) =
|
wenzelm@16601
|
682 |
if T <> propT then
|
wenzelm@16601
|
683 |
raise THM ("implies_intr: assumptions must have type prop", 0, [th])
|
wenzelm@16601
|
684 |
else
|
wenzelm@37309
|
685 |
Thm (deriv_rule1 (Proofterm.implies_intr_proof A) der,
|
wenzelm@28321
|
686 |
{thy_ref = merge_thys1 ct th,
|
wenzelm@21646
|
687 |
tags = [],
|
wenzelm@16601
|
688 |
maxidx = Int.max (maxidxA, maxidx),
|
wenzelm@16601
|
689 |
shyps = Sorts.union sorts shyps,
|
wenzelm@28354
|
690 |
hyps = remove_hyps A hyps,
|
wenzelm@16601
|
691 |
tpairs = tpairs,
|
wenzelm@28321
|
692 |
prop = Logic.mk_implies (A, prop)});
|
clasohm@0
|
693 |
|
paulson@1529
|
694 |
|
wenzelm@1220
|
695 |
(*Implication elimination
|
wenzelm@1220
|
696 |
A ==> B A
|
wenzelm@1220
|
697 |
------------
|
wenzelm@1220
|
698 |
B
|
wenzelm@1220
|
699 |
*)
|
wenzelm@16601
|
700 |
fun implies_elim thAB thA =
|
wenzelm@16601
|
701 |
let
|
wenzelm@28321
|
702 |
val Thm (derA, {maxidx = maxA, hyps = hypsA, shyps = shypsA, tpairs = tpairsA,
|
wenzelm@28321
|
703 |
prop = propA, ...}) = thA
|
wenzelm@28321
|
704 |
and Thm (der, {maxidx, hyps, shyps, tpairs, prop, ...}) = thAB;
|
wenzelm@16601
|
705 |
fun err () = raise THM ("implies_elim: major premise", 0, [thAB, thA]);
|
wenzelm@16601
|
706 |
in
|
wenzelm@16601
|
707 |
case prop of
|
wenzelm@20512
|
708 |
Const ("==>", _) $ A $ B =>
|
wenzelm@20512
|
709 |
if A aconv propA then
|
wenzelm@37309
|
710 |
Thm (deriv_rule2 (curry Proofterm.%%) der derA,
|
wenzelm@28321
|
711 |
{thy_ref = merge_thys2 thAB thA,
|
wenzelm@21646
|
712 |
tags = [],
|
wenzelm@16601
|
713 |
maxidx = Int.max (maxA, maxidx),
|
wenzelm@16601
|
714 |
shyps = Sorts.union shypsA shyps,
|
wenzelm@16601
|
715 |
hyps = union_hyps hypsA hyps,
|
wenzelm@16601
|
716 |
tpairs = union_tpairs tpairsA tpairs,
|
wenzelm@28321
|
717 |
prop = B})
|
wenzelm@16601
|
718 |
else err ()
|
wenzelm@16601
|
719 |
| _ => err ()
|
wenzelm@16601
|
720 |
end;
|
wenzelm@250
|
721 |
|
wenzelm@1220
|
722 |
(*Forall introduction. The Free or Var x must not be free in the hypotheses.
|
wenzelm@16656
|
723 |
[x]
|
wenzelm@16656
|
724 |
:
|
wenzelm@16656
|
725 |
A
|
wenzelm@16656
|
726 |
------
|
wenzelm@16656
|
727 |
!!x. A
|
wenzelm@1220
|
728 |
*)
|
wenzelm@16601
|
729 |
fun forall_intr
|
wenzelm@16601
|
730 |
(ct as Cterm {t = x, T, sorts, ...})
|
wenzelm@28321
|
731 |
(th as Thm (der, {maxidx, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@16601
|
732 |
let
|
wenzelm@16601
|
733 |
fun result a =
|
wenzelm@37309
|
734 |
Thm (deriv_rule1 (Proofterm.forall_intr_proof x a) der,
|
wenzelm@28321
|
735 |
{thy_ref = merge_thys1 ct th,
|
wenzelm@21646
|
736 |
tags = [],
|
wenzelm@16601
|
737 |
maxidx = maxidx,
|
wenzelm@16601
|
738 |
shyps = Sorts.union sorts shyps,
|
wenzelm@16601
|
739 |
hyps = hyps,
|
wenzelm@16601
|
740 |
tpairs = tpairs,
|
wenzelm@28321
|
741 |
prop = Term.all T $ Abs (a, T, abstract_over (x, prop))});
|
wenzelm@21798
|
742 |
fun check_occs a x ts =
|
wenzelm@16847
|
743 |
if exists (fn t => Logic.occs (x, t)) ts then
|
wenzelm@21798
|
744 |
raise THM ("forall_intr: variable " ^ quote a ^ " free in assumptions", 0, [th])
|
wenzelm@16601
|
745 |
else ();
|
wenzelm@16601
|
746 |
in
|
wenzelm@16601
|
747 |
case x of
|
wenzelm@21798
|
748 |
Free (a, _) => (check_occs a x hyps; check_occs a x (terms_of_tpairs tpairs); result a)
|
wenzelm@21798
|
749 |
| Var ((a, _), _) => (check_occs a x (terms_of_tpairs tpairs); result a)
|
wenzelm@16601
|
750 |
| _ => raise THM ("forall_intr: not a variable", 0, [th])
|
clasohm@0
|
751 |
end;
|
clasohm@0
|
752 |
|
wenzelm@1220
|
753 |
(*Forall elimination
|
wenzelm@16656
|
754 |
!!x. A
|
wenzelm@1220
|
755 |
------
|
wenzelm@1220
|
756 |
A[t/x]
|
wenzelm@1220
|
757 |
*)
|
wenzelm@16601
|
758 |
fun forall_elim
|
wenzelm@16601
|
759 |
(ct as Cterm {t, T, maxidx = maxt, sorts, ...})
|
wenzelm@28321
|
760 |
(th as Thm (der, {maxidx, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@16601
|
761 |
(case prop of
|
wenzelm@16601
|
762 |
Const ("all", Type ("fun", [Type ("fun", [qary, _]), _])) $ A =>
|
wenzelm@16601
|
763 |
if T <> qary then
|
wenzelm@16601
|
764 |
raise THM ("forall_elim: type mismatch", 0, [th])
|
wenzelm@16601
|
765 |
else
|
wenzelm@37309
|
766 |
Thm (deriv_rule1 (Proofterm.% o rpair (SOME t)) der,
|
wenzelm@28321
|
767 |
{thy_ref = merge_thys1 ct th,
|
wenzelm@21646
|
768 |
tags = [],
|
wenzelm@16601
|
769 |
maxidx = Int.max (maxidx, maxt),
|
wenzelm@16601
|
770 |
shyps = Sorts.union sorts shyps,
|
wenzelm@16601
|
771 |
hyps = hyps,
|
wenzelm@16601
|
772 |
tpairs = tpairs,
|
wenzelm@28321
|
773 |
prop = Term.betapply (A, t)})
|
wenzelm@16601
|
774 |
| _ => raise THM ("forall_elim: not quantified", 0, [th]));
|
clasohm@0
|
775 |
|
clasohm@0
|
776 |
|
wenzelm@1220
|
777 |
(* Equality *)
|
clasohm@0
|
778 |
|
wenzelm@16601
|
779 |
(*Reflexivity
|
wenzelm@16601
|
780 |
t == t
|
wenzelm@16601
|
781 |
*)
|
wenzelm@32791
|
782 |
fun reflexive (Cterm {thy_ref, t, T = _, maxidx, sorts}) =
|
wenzelm@37309
|
783 |
Thm (deriv_rule0 Proofterm.reflexive,
|
wenzelm@28321
|
784 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
785 |
tags = [],
|
wenzelm@16601
|
786 |
maxidx = maxidx,
|
wenzelm@16601
|
787 |
shyps = sorts,
|
wenzelm@16601
|
788 |
hyps = [],
|
wenzelm@16601
|
789 |
tpairs = [],
|
wenzelm@28321
|
790 |
prop = Logic.mk_equals (t, t)});
|
wenzelm@16601
|
791 |
|
wenzelm@16601
|
792 |
(*Symmetry
|
wenzelm@16601
|
793 |
t == u
|
wenzelm@16601
|
794 |
------
|
wenzelm@16601
|
795 |
u == t
|
wenzelm@16601
|
796 |
*)
|
wenzelm@28321
|
797 |
fun symmetric (th as Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@16601
|
798 |
(case prop of
|
wenzelm@32791
|
799 |
(eq as Const ("==", _)) $ t $ u =>
|
wenzelm@37309
|
800 |
Thm (deriv_rule1 Proofterm.symmetric der,
|
wenzelm@28321
|
801 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
802 |
tags = [],
|
wenzelm@16601
|
803 |
maxidx = maxidx,
|
wenzelm@16601
|
804 |
shyps = shyps,
|
wenzelm@16601
|
805 |
hyps = hyps,
|
wenzelm@16601
|
806 |
tpairs = tpairs,
|
wenzelm@28321
|
807 |
prop = eq $ u $ t})
|
wenzelm@16601
|
808 |
| _ => raise THM ("symmetric", 0, [th]));
|
wenzelm@16601
|
809 |
|
wenzelm@16601
|
810 |
(*Transitivity
|
wenzelm@16601
|
811 |
t1 == u u == t2
|
wenzelm@16601
|
812 |
------------------
|
wenzelm@16601
|
813 |
t1 == t2
|
wenzelm@16601
|
814 |
*)
|
wenzelm@16601
|
815 |
fun transitive th1 th2 =
|
wenzelm@16601
|
816 |
let
|
wenzelm@28321
|
817 |
val Thm (der1, {maxidx = max1, hyps = hyps1, shyps = shyps1, tpairs = tpairs1,
|
wenzelm@28321
|
818 |
prop = prop1, ...}) = th1
|
wenzelm@28321
|
819 |
and Thm (der2, {maxidx = max2, hyps = hyps2, shyps = shyps2, tpairs = tpairs2,
|
wenzelm@28321
|
820 |
prop = prop2, ...}) = th2;
|
wenzelm@16601
|
821 |
fun err msg = raise THM ("transitive: " ^ msg, 0, [th1, th2]);
|
wenzelm@16601
|
822 |
in
|
wenzelm@16601
|
823 |
case (prop1, prop2) of
|
wenzelm@16601
|
824 |
((eq as Const ("==", Type (_, [T, _]))) $ t1 $ u, Const ("==", _) $ u' $ t2) =>
|
wenzelm@16601
|
825 |
if not (u aconv u') then err "middle term"
|
wenzelm@16601
|
826 |
else
|
wenzelm@37309
|
827 |
Thm (deriv_rule2 (Proofterm.transitive u T) der1 der2,
|
wenzelm@28321
|
828 |
{thy_ref = merge_thys2 th1 th2,
|
wenzelm@21646
|
829 |
tags = [],
|
wenzelm@16601
|
830 |
maxidx = Int.max (max1, max2),
|
wenzelm@16601
|
831 |
shyps = Sorts.union shyps1 shyps2,
|
wenzelm@16601
|
832 |
hyps = union_hyps hyps1 hyps2,
|
wenzelm@16601
|
833 |
tpairs = union_tpairs tpairs1 tpairs2,
|
wenzelm@28321
|
834 |
prop = eq $ t1 $ t2})
|
wenzelm@16601
|
835 |
| _ => err "premises"
|
clasohm@0
|
836 |
end;
|
clasohm@0
|
837 |
|
wenzelm@16601
|
838 |
(*Beta-conversion
|
wenzelm@16656
|
839 |
(%x. t)(u) == t[u/x]
|
wenzelm@16601
|
840 |
fully beta-reduces the term if full = true
|
wenzelm@1220
|
841 |
*)
|
wenzelm@32791
|
842 |
fun beta_conversion full (Cterm {thy_ref, t, T = _, maxidx, sorts}) =
|
wenzelm@16601
|
843 |
let val t' =
|
wenzelm@16601
|
844 |
if full then Envir.beta_norm t
|
wenzelm@16601
|
845 |
else
|
wenzelm@16601
|
846 |
(case t of Abs (_, _, bodt) $ u => subst_bound (u, bodt)
|
wenzelm@16601
|
847 |
| _ => raise THM ("beta_conversion: not a redex", 0, []));
|
wenzelm@16601
|
848 |
in
|
wenzelm@37309
|
849 |
Thm (deriv_rule0 Proofterm.reflexive,
|
wenzelm@28321
|
850 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
851 |
tags = [],
|
wenzelm@16601
|
852 |
maxidx = maxidx,
|
wenzelm@16601
|
853 |
shyps = sorts,
|
wenzelm@16601
|
854 |
hyps = [],
|
wenzelm@16601
|
855 |
tpairs = [],
|
wenzelm@28321
|
856 |
prop = Logic.mk_equals (t, t')})
|
clasohm@0
|
857 |
end;
|
clasohm@0
|
858 |
|
wenzelm@32791
|
859 |
fun eta_conversion (Cterm {thy_ref, t, T = _, maxidx, sorts}) =
|
wenzelm@37309
|
860 |
Thm (deriv_rule0 Proofterm.reflexive,
|
wenzelm@28321
|
861 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
862 |
tags = [],
|
wenzelm@16601
|
863 |
maxidx = maxidx,
|
wenzelm@16601
|
864 |
shyps = sorts,
|
wenzelm@16601
|
865 |
hyps = [],
|
wenzelm@16601
|
866 |
tpairs = [],
|
wenzelm@28321
|
867 |
prop = Logic.mk_equals (t, Envir.eta_contract t)});
|
clasohm@0
|
868 |
|
wenzelm@32791
|
869 |
fun eta_long_conversion (Cterm {thy_ref, t, T = _, maxidx, sorts}) =
|
wenzelm@37309
|
870 |
Thm (deriv_rule0 Proofterm.reflexive,
|
wenzelm@28321
|
871 |
{thy_ref = thy_ref,
|
wenzelm@23493
|
872 |
tags = [],
|
wenzelm@23493
|
873 |
maxidx = maxidx,
|
wenzelm@23493
|
874 |
shyps = sorts,
|
wenzelm@23493
|
875 |
hyps = [],
|
wenzelm@23493
|
876 |
tpairs = [],
|
wenzelm@28321
|
877 |
prop = Logic.mk_equals (t, Pattern.eta_long [] t)});
|
wenzelm@23493
|
878 |
|
clasohm@0
|
879 |
(*The abstraction rule. The Free or Var x must not be free in the hypotheses.
|
clasohm@0
|
880 |
The bound variable will be named "a" (since x will be something like x320)
|
wenzelm@16601
|
881 |
t == u
|
wenzelm@16601
|
882 |
--------------
|
wenzelm@16601
|
883 |
%x. t == %x. u
|
wenzelm@1220
|
884 |
*)
|
wenzelm@16601
|
885 |
fun abstract_rule a
|
wenzelm@16601
|
886 |
(Cterm {t = x, T, sorts, ...})
|
wenzelm@28321
|
887 |
(th as Thm (der, {thy_ref, maxidx, hyps, shyps, tpairs, prop, ...})) =
|
wenzelm@16601
|
888 |
let
|
wenzelm@16601
|
889 |
val (t, u) = Logic.dest_equals prop
|
wenzelm@16601
|
890 |
handle TERM _ => raise THM ("abstract_rule: premise not an equality", 0, [th]);
|
wenzelm@16601
|
891 |
val result =
|
wenzelm@37309
|
892 |
Thm (deriv_rule1 (Proofterm.abstract_rule x a) der,
|
wenzelm@28321
|
893 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
894 |
tags = [],
|
wenzelm@16601
|
895 |
maxidx = maxidx,
|
wenzelm@16601
|
896 |
shyps = Sorts.union sorts shyps,
|
wenzelm@16601
|
897 |
hyps = hyps,
|
wenzelm@16601
|
898 |
tpairs = tpairs,
|
wenzelm@16601
|
899 |
prop = Logic.mk_equals
|
wenzelm@28321
|
900 |
(Abs (a, T, abstract_over (x, t)), Abs (a, T, abstract_over (x, u)))});
|
wenzelm@21798
|
901 |
fun check_occs a x ts =
|
wenzelm@16847
|
902 |
if exists (fn t => Logic.occs (x, t)) ts then
|
wenzelm@21798
|
903 |
raise THM ("abstract_rule: variable " ^ quote a ^ " free in assumptions", 0, [th])
|
wenzelm@16601
|
904 |
else ();
|
wenzelm@16601
|
905 |
in
|
wenzelm@16601
|
906 |
case x of
|
wenzelm@21798
|
907 |
Free (a, _) => (check_occs a x hyps; check_occs a x (terms_of_tpairs tpairs); result)
|
wenzelm@21798
|
908 |
| Var ((a, _), _) => (check_occs a x (terms_of_tpairs tpairs); result)
|
wenzelm@21798
|
909 |
| _ => raise THM ("abstract_rule: not a variable", 0, [th])
|
clasohm@0
|
910 |
end;
|
clasohm@0
|
911 |
|
clasohm@0
|
912 |
(*The combination rule
|
wenzelm@3529
|
913 |
f == g t == u
|
wenzelm@3529
|
914 |
--------------
|
wenzelm@16601
|
915 |
f t == g u
|
wenzelm@1220
|
916 |
*)
|
clasohm@0
|
917 |
fun combination th1 th2 =
|
wenzelm@16601
|
918 |
let
|
wenzelm@28321
|
919 |
val Thm (der1, {maxidx = max1, shyps = shyps1, hyps = hyps1, tpairs = tpairs1,
|
wenzelm@28321
|
920 |
prop = prop1, ...}) = th1
|
wenzelm@28321
|
921 |
and Thm (der2, {maxidx = max2, shyps = shyps2, hyps = hyps2, tpairs = tpairs2,
|
wenzelm@28321
|
922 |
prop = prop2, ...}) = th2;
|
wenzelm@16601
|
923 |
fun chktypes fT tT =
|
wenzelm@16601
|
924 |
(case fT of
|
wenzelm@32791
|
925 |
Type ("fun", [T1, _]) =>
|
wenzelm@16601
|
926 |
if T1 <> tT then
|
wenzelm@16601
|
927 |
raise THM ("combination: types", 0, [th1, th2])
|
wenzelm@16601
|
928 |
else ()
|
wenzelm@16601
|
929 |
| _ => raise THM ("combination: not function type", 0, [th1, th2]));
|
wenzelm@16601
|
930 |
in
|
wenzelm@16601
|
931 |
case (prop1, prop2) of
|
wenzelm@16601
|
932 |
(Const ("==", Type ("fun", [fT, _])) $ f $ g,
|
wenzelm@16601
|
933 |
Const ("==", Type ("fun", [tT, _])) $ t $ u) =>
|
wenzelm@16601
|
934 |
(chktypes fT tT;
|
wenzelm@37309
|
935 |
Thm (deriv_rule2 (Proofterm.combination f g t u fT) der1 der2,
|
wenzelm@28321
|
936 |
{thy_ref = merge_thys2 th1 th2,
|
wenzelm@21646
|
937 |
tags = [],
|
wenzelm@16601
|
938 |
maxidx = Int.max (max1, max2),
|
wenzelm@16601
|
939 |
shyps = Sorts.union shyps1 shyps2,
|
wenzelm@16601
|
940 |
hyps = union_hyps hyps1 hyps2,
|
wenzelm@16601
|
941 |
tpairs = union_tpairs tpairs1 tpairs2,
|
wenzelm@28321
|
942 |
prop = Logic.mk_equals (f $ t, g $ u)}))
|
wenzelm@16601
|
943 |
| _ => raise THM ("combination: premises", 0, [th1, th2])
|
clasohm@0
|
944 |
end;
|
clasohm@0
|
945 |
|
wenzelm@16601
|
946 |
(*Equality introduction
|
wenzelm@3529
|
947 |
A ==> B B ==> A
|
wenzelm@3529
|
948 |
----------------
|
wenzelm@3529
|
949 |
A == B
|
paulson@1529
|
950 |
*)
|
paulson@1529
|
951 |
fun equal_intr th1 th2 =
|
wenzelm@16601
|
952 |
let
|
wenzelm@28321
|
953 |
val Thm (der1, {maxidx = max1, shyps = shyps1, hyps = hyps1, tpairs = tpairs1,
|
wenzelm@28321
|
954 |
prop = prop1, ...}) = th1
|
wenzelm@28321
|
955 |
and Thm (der2, {maxidx = max2, shyps = shyps2, hyps = hyps2, tpairs = tpairs2,
|
wenzelm@28321
|
956 |
prop = prop2, ...}) = th2;
|
wenzelm@16601
|
957 |
fun err msg = raise THM ("equal_intr: " ^ msg, 0, [th1, th2]);
|
wenzelm@16601
|
958 |
in
|
wenzelm@16601
|
959 |
case (prop1, prop2) of
|
wenzelm@16601
|
960 |
(Const("==>", _) $ A $ B, Const("==>", _) $ B' $ A') =>
|
wenzelm@16601
|
961 |
if A aconv A' andalso B aconv B' then
|
wenzelm@37309
|
962 |
Thm (deriv_rule2 (Proofterm.equal_intr A B) der1 der2,
|
wenzelm@28321
|
963 |
{thy_ref = merge_thys2 th1 th2,
|
wenzelm@21646
|
964 |
tags = [],
|
wenzelm@16601
|
965 |
maxidx = Int.max (max1, max2),
|
wenzelm@16601
|
966 |
shyps = Sorts.union shyps1 shyps2,
|
wenzelm@16601
|
967 |
hyps = union_hyps hyps1 hyps2,
|
wenzelm@16601
|
968 |
tpairs = union_tpairs tpairs1 tpairs2,
|
wenzelm@28321
|
969 |
prop = Logic.mk_equals (A, B)})
|
wenzelm@16601
|
970 |
else err "not equal"
|
wenzelm@16601
|
971 |
| _ => err "premises"
|
paulson@1529
|
972 |
end;
|
paulson@1529
|
973 |
|
clasohm@0
|
974 |
(*The equal propositions rule
|
wenzelm@3529
|
975 |
A == B A
|
wenzelm@1220
|
976 |
---------
|
wenzelm@1220
|
977 |
B
|
wenzelm@1220
|
978 |
*)
|
clasohm@0
|
979 |
fun equal_elim th1 th2 =
|
wenzelm@16601
|
980 |
let
|
wenzelm@28321
|
981 |
val Thm (der1, {maxidx = max1, shyps = shyps1, hyps = hyps1,
|
wenzelm@28321
|
982 |
tpairs = tpairs1, prop = prop1, ...}) = th1
|
wenzelm@28321
|
983 |
and Thm (der2, {maxidx = max2, shyps = shyps2, hyps = hyps2,
|
wenzelm@28321
|
984 |
tpairs = tpairs2, prop = prop2, ...}) = th2;
|
wenzelm@16601
|
985 |
fun err msg = raise THM ("equal_elim: " ^ msg, 0, [th1, th2]);
|
wenzelm@16601
|
986 |
in
|
wenzelm@16601
|
987 |
case prop1 of
|
wenzelm@16601
|
988 |
Const ("==", _) $ A $ B =>
|
wenzelm@16601
|
989 |
if prop2 aconv A then
|
wenzelm@37309
|
990 |
Thm (deriv_rule2 (Proofterm.equal_elim A B) der1 der2,
|
wenzelm@28321
|
991 |
{thy_ref = merge_thys2 th1 th2,
|
wenzelm@21646
|
992 |
tags = [],
|
wenzelm@16601
|
993 |
maxidx = Int.max (max1, max2),
|
wenzelm@16601
|
994 |
shyps = Sorts.union shyps1 shyps2,
|
wenzelm@16601
|
995 |
hyps = union_hyps hyps1 hyps2,
|
wenzelm@16601
|
996 |
tpairs = union_tpairs tpairs1 tpairs2,
|
wenzelm@28321
|
997 |
prop = B})
|
wenzelm@16601
|
998 |
else err "not equal"
|
clasohm@0
|
999 |
| _ => err"major premise"
|
clasohm@0
|
1000 |
end;
|
clasohm@0
|
1001 |
|
clasohm@0
|
1002 |
|
wenzelm@1220
|
1003 |
|
clasohm@0
|
1004 |
(**** Derived rules ****)
|
clasohm@0
|
1005 |
|
wenzelm@16601
|
1006 |
(*Smash unifies the list of term pairs leaving no flex-flex pairs.
|
wenzelm@24143
|
1007 |
Instantiates the theorem and deletes trivial tpairs. Resulting
|
wenzelm@24143
|
1008 |
sequence may contain multiple elements if the tpairs are not all
|
wenzelm@24143
|
1009 |
flex-flex.*)
|
wenzelm@28321
|
1010 |
fun flexflex_rule (th as Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@24143
|
1011 |
let val thy = Theory.deref thy_ref in
|
wenzelm@24143
|
1012 |
Unify.smash_unifiers thy tpairs (Envir.empty maxidx)
|
wenzelm@24143
|
1013 |
|> Seq.map (fn env =>
|
wenzelm@24143
|
1014 |
if Envir.is_empty env then th
|
wenzelm@24143
|
1015 |
else
|
wenzelm@24143
|
1016 |
let
|
wenzelm@24143
|
1017 |
val tpairs' = tpairs |> map (pairself (Envir.norm_term env))
|
wenzelm@24143
|
1018 |
(*remove trivial tpairs, of the form t==t*)
|
wenzelm@24143
|
1019 |
|> filter_out (op aconv);
|
wenzelm@37309
|
1020 |
val der' = deriv_rule1 (Proofterm.norm_proof' env) der;
|
wenzelm@24143
|
1021 |
val prop' = Envir.norm_term env prop;
|
wenzelm@24143
|
1022 |
val maxidx = maxidx_tpairs tpairs' (maxidx_of_term prop');
|
wenzelm@26640
|
1023 |
val shyps = Envir.insert_sorts env shyps;
|
wenzelm@24143
|
1024 |
in
|
wenzelm@28321
|
1025 |
Thm (der', {thy_ref = Theory.check_thy thy, tags = [], maxidx = maxidx,
|
wenzelm@28321
|
1026 |
shyps = shyps, hyps = hyps, tpairs = tpairs', prop = prop'})
|
wenzelm@24143
|
1027 |
end)
|
wenzelm@24143
|
1028 |
end;
|
wenzelm@16601
|
1029 |
|
clasohm@0
|
1030 |
|
wenzelm@19910
|
1031 |
(*Generalization of fixed variables
|
wenzelm@19910
|
1032 |
A
|
wenzelm@19910
|
1033 |
--------------------
|
wenzelm@19910
|
1034 |
A[?'a/'a, ?x/x, ...]
|
wenzelm@19910
|
1035 |
*)
|
wenzelm@19910
|
1036 |
|
wenzelm@19910
|
1037 |
fun generalize ([], []) _ th = th
|
wenzelm@19910
|
1038 |
| generalize (tfrees, frees) idx th =
|
wenzelm@19910
|
1039 |
let
|
wenzelm@28321
|
1040 |
val Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...}) = th;
|
wenzelm@19910
|
1041 |
val _ = idx <= maxidx andalso raise THM ("generalize: bad index", idx, [th]);
|
wenzelm@19910
|
1042 |
|
wenzelm@33697
|
1043 |
val bad_type =
|
wenzelm@33697
|
1044 |
if null tfrees then K false
|
wenzelm@33697
|
1045 |
else Term.exists_subtype (fn TFree (a, _) => member (op =) tfrees a | _ => false);
|
wenzelm@19910
|
1046 |
fun bad_term (Free (x, T)) = bad_type T orelse member (op =) frees x
|
wenzelm@19910
|
1047 |
| bad_term (Var (_, T)) = bad_type T
|
wenzelm@19910
|
1048 |
| bad_term (Const (_, T)) = bad_type T
|
wenzelm@19910
|
1049 |
| bad_term (Abs (_, T, t)) = bad_type T orelse bad_term t
|
wenzelm@19910
|
1050 |
| bad_term (t $ u) = bad_term t orelse bad_term u
|
wenzelm@19910
|
1051 |
| bad_term (Bound _) = false;
|
wenzelm@19910
|
1052 |
val _ = exists bad_term hyps andalso
|
wenzelm@19910
|
1053 |
raise THM ("generalize: variable free in assumptions", 0, [th]);
|
wenzelm@19910
|
1054 |
|
wenzelm@31979
|
1055 |
val gen = Term_Subst.generalize (tfrees, frees) idx;
|
wenzelm@19910
|
1056 |
val prop' = gen prop;
|
wenzelm@19910
|
1057 |
val tpairs' = map (pairself gen) tpairs;
|
wenzelm@19910
|
1058 |
val maxidx' = maxidx_tpairs tpairs' (maxidx_of_term prop');
|
wenzelm@19910
|
1059 |
in
|
wenzelm@37309
|
1060 |
Thm (deriv_rule1 (Proofterm.generalize (tfrees, frees) idx) der,
|
wenzelm@28321
|
1061 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1062 |
tags = [],
|
wenzelm@19910
|
1063 |
maxidx = maxidx',
|
wenzelm@19910
|
1064 |
shyps = shyps,
|
wenzelm@19910
|
1065 |
hyps = hyps,
|
wenzelm@19910
|
1066 |
tpairs = tpairs',
|
wenzelm@28321
|
1067 |
prop = prop'})
|
wenzelm@19910
|
1068 |
end;
|
wenzelm@19910
|
1069 |
|
wenzelm@19910
|
1070 |
|
wenzelm@22584
|
1071 |
(*Instantiation of schematic variables
|
wenzelm@16656
|
1072 |
A
|
wenzelm@16656
|
1073 |
--------------------
|
wenzelm@16656
|
1074 |
A[t1/v1, ..., tn/vn]
|
wenzelm@1220
|
1075 |
*)
|
clasohm@0
|
1076 |
|
wenzelm@6928
|
1077 |
local
|
wenzelm@6928
|
1078 |
|
wenzelm@26939
|
1079 |
fun pretty_typing thy t T = Pretty.block
|
wenzelm@26939
|
1080 |
[Syntax.pretty_term_global thy t, Pretty.str " ::", Pretty.brk 1, Syntax.pretty_typ_global thy T];
|
wenzelm@16425
|
1081 |
|
wenzelm@16884
|
1082 |
fun add_inst (ct, cu) (thy_ref, sorts) =
|
wenzelm@16425
|
1083 |
let
|
wenzelm@26939
|
1084 |
val Cterm {t = t, T = T, ...} = ct;
|
wenzelm@26939
|
1085 |
val Cterm {t = u, T = U, sorts = sorts_u, maxidx = maxidx_u, ...} = cu;
|
wenzelm@16884
|
1086 |
val thy_ref' = Theory.merge_refs (thy_ref, merge_thys0 ct cu);
|
wenzelm@16884
|
1087 |
val sorts' = Sorts.union sorts_u sorts;
|
wenzelm@16425
|
1088 |
in
|
wenzelm@16884
|
1089 |
(case t of Var v =>
|
wenzelm@20512
|
1090 |
if T = U then ((v, (u, maxidx_u)), (thy_ref', sorts'))
|
wenzelm@16884
|
1091 |
else raise TYPE (Pretty.string_of (Pretty.block
|
wenzelm@16884
|
1092 |
[Pretty.str "instantiate: type conflict",
|
wenzelm@16884
|
1093 |
Pretty.fbrk, pretty_typing (Theory.deref thy_ref') t T,
|
wenzelm@16884
|
1094 |
Pretty.fbrk, pretty_typing (Theory.deref thy_ref') u U]), [T, U], [t, u])
|
wenzelm@16884
|
1095 |
| _ => raise TYPE (Pretty.string_of (Pretty.block
|
wenzelm@16884
|
1096 |
[Pretty.str "instantiate: not a variable",
|
wenzelm@26939
|
1097 |
Pretty.fbrk, Syntax.pretty_term_global (Theory.deref thy_ref') t]), [], [t]))
|
wenzelm@6928
|
1098 |
end;
|
wenzelm@6928
|
1099 |
|
wenzelm@16884
|
1100 |
fun add_instT (cT, cU) (thy_ref, sorts) =
|
wenzelm@16656
|
1101 |
let
|
wenzelm@16884
|
1102 |
val Ctyp {T, thy_ref = thy_ref1, ...} = cT
|
wenzelm@20512
|
1103 |
and Ctyp {T = U, thy_ref = thy_ref2, sorts = sorts_U, maxidx = maxidx_U, ...} = cU;
|
wenzelm@24143
|
1104 |
val thy' = Theory.deref (Theory.merge_refs (thy_ref, Theory.merge_refs (thy_ref1, thy_ref2)));
|
wenzelm@16884
|
1105 |
val sorts' = Sorts.union sorts_U sorts;
|
wenzelm@16656
|
1106 |
in
|
wenzelm@16884
|
1107 |
(case T of TVar (v as (_, S)) =>
|
wenzelm@24143
|
1108 |
if Sign.of_sort thy' (U, S) then ((v, (U, maxidx_U)), (Theory.check_thy thy', sorts'))
|
wenzelm@26939
|
1109 |
else raise TYPE ("Type not of sort " ^ Syntax.string_of_sort_global thy' S, [U], [])
|
wenzelm@16656
|
1110 |
| _ => raise TYPE (Pretty.string_of (Pretty.block
|
berghofe@15797
|
1111 |
[Pretty.str "instantiate: not a type variable",
|
wenzelm@26939
|
1112 |
Pretty.fbrk, Syntax.pretty_typ_global thy' T]), [T], []))
|
wenzelm@16656
|
1113 |
end;
|
clasohm@0
|
1114 |
|
wenzelm@6928
|
1115 |
in
|
wenzelm@6928
|
1116 |
|
wenzelm@16601
|
1117 |
(*Left-to-right replacements: ctpairs = [..., (vi, ti), ...].
|
clasohm@0
|
1118 |
Instantiates distinct Vars by terms of same type.
|
wenzelm@16601
|
1119 |
Does NOT normalize the resulting theorem!*)
|
paulson@1529
|
1120 |
fun instantiate ([], []) th = th
|
wenzelm@16884
|
1121 |
| instantiate (instT, inst) th =
|
wenzelm@16656
|
1122 |
let
|
wenzelm@28321
|
1123 |
val Thm (der, {thy_ref, hyps, shyps, tpairs, prop, ...}) = th;
|
wenzelm@16884
|
1124 |
val (inst', (instT', (thy_ref', shyps'))) =
|
wenzelm@16884
|
1125 |
(thy_ref, shyps) |> fold_map add_inst inst ||> fold_map add_instT instT;
|
wenzelm@31979
|
1126 |
val subst = Term_Subst.instantiate_maxidx (instT', inst');
|
wenzelm@20512
|
1127 |
val (prop', maxidx1) = subst prop ~1;
|
wenzelm@20512
|
1128 |
val (tpairs', maxidx') =
|
wenzelm@20512
|
1129 |
fold_map (fn (t, u) => fn i => subst t i ||>> subst u) tpairs maxidx1;
|
wenzelm@16656
|
1130 |
in
|
wenzelm@37309
|
1131 |
Thm (deriv_rule1
|
wenzelm@37309
|
1132 |
(fn d => Proofterm.instantiate (map (apsnd #1) instT', map (apsnd #1) inst') d) der,
|
wenzelm@28321
|
1133 |
{thy_ref = thy_ref',
|
wenzelm@21646
|
1134 |
tags = [],
|
wenzelm@20545
|
1135 |
maxidx = maxidx',
|
wenzelm@20545
|
1136 |
shyps = shyps',
|
wenzelm@20545
|
1137 |
hyps = hyps,
|
wenzelm@20545
|
1138 |
tpairs = tpairs',
|
wenzelm@28321
|
1139 |
prop = prop'})
|
wenzelm@16656
|
1140 |
end
|
wenzelm@16656
|
1141 |
handle TYPE (msg, _, _) => raise THM (msg, 0, [th]);
|
wenzelm@6928
|
1142 |
|
wenzelm@22584
|
1143 |
fun instantiate_cterm ([], []) ct = ct
|
wenzelm@22584
|
1144 |
| instantiate_cterm (instT, inst) ct =
|
wenzelm@22584
|
1145 |
let
|
wenzelm@22584
|
1146 |
val Cterm {thy_ref, t, T, sorts, ...} = ct;
|
wenzelm@22584
|
1147 |
val (inst', (instT', (thy_ref', sorts'))) =
|
wenzelm@22584
|
1148 |
(thy_ref, sorts) |> fold_map add_inst inst ||> fold_map add_instT instT;
|
wenzelm@31979
|
1149 |
val subst = Term_Subst.instantiate_maxidx (instT', inst');
|
wenzelm@31979
|
1150 |
val substT = Term_Subst.instantiateT_maxidx instT';
|
wenzelm@22584
|
1151 |
val (t', maxidx1) = subst t ~1;
|
wenzelm@22584
|
1152 |
val (T', maxidx') = substT T maxidx1;
|
wenzelm@22584
|
1153 |
in Cterm {thy_ref = thy_ref', t = t', T = T', sorts = sorts', maxidx = maxidx'} end
|
wenzelm@22584
|
1154 |
handle TYPE (msg, _, _) => raise CTERM (msg, [ct]);
|
wenzelm@22584
|
1155 |
|
wenzelm@6928
|
1156 |
end;
|
wenzelm@6928
|
1157 |
|
clasohm@0
|
1158 |
|
wenzelm@16601
|
1159 |
(*The trivial implication A ==> A, justified by assume and forall rules.
|
wenzelm@16601
|
1160 |
A can contain Vars, not so for assume!*)
|
wenzelm@16601
|
1161 |
fun trivial (Cterm {thy_ref, t =A, T, maxidx, sorts}) =
|
wenzelm@16601
|
1162 |
if T <> propT then
|
wenzelm@16601
|
1163 |
raise THM ("trivial: the term must have type prop", 0, [])
|
wenzelm@16601
|
1164 |
else
|
wenzelm@37309
|
1165 |
Thm (deriv_rule0 (Proofterm.AbsP ("H", NONE, Proofterm.PBound 0)),
|
wenzelm@28321
|
1166 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1167 |
tags = [],
|
wenzelm@16601
|
1168 |
maxidx = maxidx,
|
wenzelm@16601
|
1169 |
shyps = sorts,
|
wenzelm@16601
|
1170 |
hyps = [],
|
wenzelm@16601
|
1171 |
tpairs = [],
|
wenzelm@28321
|
1172 |
prop = Logic.mk_implies (A, A)});
|
clasohm@0
|
1173 |
|
wenzelm@31944
|
1174 |
(*Axiom-scheme reflecting signature contents
|
wenzelm@31944
|
1175 |
T :: c
|
wenzelm@31944
|
1176 |
-------------------
|
wenzelm@31944
|
1177 |
OFCLASS(T, c_class)
|
wenzelm@31944
|
1178 |
*)
|
wenzelm@31944
|
1179 |
fun of_class (cT, raw_c) =
|
wenzelm@24143
|
1180 |
let
|
wenzelm@31944
|
1181 |
val Ctyp {thy_ref, T, ...} = cT;
|
wenzelm@31944
|
1182 |
val thy = Theory.deref thy_ref;
|
wenzelm@31914
|
1183 |
val c = Sign.certify_class thy raw_c;
|
wenzelm@31944
|
1184 |
val Cterm {t = prop, maxidx, sorts, ...} = cterm_of thy (Logic.mk_of_class (T, c));
|
wenzelm@399
|
1185 |
in
|
wenzelm@31944
|
1186 |
if Sign.of_sort thy (T, [c]) then
|
wenzelm@37309
|
1187 |
Thm (deriv_rule0 (Proofterm.OfClass (T, c)),
|
wenzelm@31944
|
1188 |
{thy_ref = Theory.check_thy thy,
|
wenzelm@31944
|
1189 |
tags = [],
|
wenzelm@31944
|
1190 |
maxidx = maxidx,
|
wenzelm@31944
|
1191 |
shyps = sorts,
|
wenzelm@31944
|
1192 |
hyps = [],
|
wenzelm@31944
|
1193 |
tpairs = [],
|
wenzelm@31944
|
1194 |
prop = prop})
|
wenzelm@31944
|
1195 |
else raise THM ("of_class: type not of class " ^ Syntax.string_of_sort_global thy [c], 0, [])
|
wenzelm@399
|
1196 |
end;
|
wenzelm@399
|
1197 |
|
wenzelm@36637
|
1198 |
(*Remove extra sorts that are witnessed by type signature information*)
|
wenzelm@36637
|
1199 |
fun strip_shyps (thm as Thm (_, {shyps = [], ...})) = thm
|
wenzelm@36637
|
1200 |
| strip_shyps (thm as Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
|
wenzelm@36637
|
1201 |
let
|
wenzelm@36637
|
1202 |
val thy = Theory.deref thy_ref;
|
wenzelm@36644
|
1203 |
val algebra = Sign.classes_of thy;
|
wenzelm@36644
|
1204 |
|
wenzelm@36644
|
1205 |
val present = (fold_terms o fold_types o fold_atyps_sorts) (insert (eq_fst op =)) thm [];
|
wenzelm@36637
|
1206 |
val extra = fold (Sorts.remove_sort o #2) present shyps;
|
wenzelm@36637
|
1207 |
val witnessed = Sign.witness_sorts thy present extra;
|
wenzelm@36637
|
1208 |
val extra' = fold (Sorts.remove_sort o #2) witnessed extra
|
wenzelm@36644
|
1209 |
|> Sorts.minimal_sorts algebra;
|
wenzelm@36637
|
1210 |
val shyps' = fold (Sorts.insert_sort o #2) present extra';
|
wenzelm@36637
|
1211 |
in
|
wenzelm@37309
|
1212 |
Thm (deriv_rule_unconditional
|
wenzelm@37309
|
1213 |
(Proofterm.strip_shyps_proof algebra present witnessed extra') der,
|
wenzelm@36644
|
1214 |
{thy_ref = Theory.check_thy thy, tags = tags, maxidx = maxidx,
|
wenzelm@36637
|
1215 |
shyps = shyps', hyps = hyps, tpairs = tpairs, prop = prop})
|
wenzelm@36637
|
1216 |
end;
|
wenzelm@36637
|
1217 |
|
wenzelm@36778
|
1218 |
(*Internalize sort constraints of type variables*)
|
wenzelm@36931
|
1219 |
fun unconstrainT (thm as Thm (der, args)) =
|
wenzelm@19505
|
1220 |
let
|
wenzelm@36931
|
1221 |
val Deriv {promises, body} = der;
|
wenzelm@36931
|
1222 |
val {thy_ref, shyps, hyps, tpairs, prop, ...} = args;
|
wenzelm@36931
|
1223 |
|
wenzelm@36778
|
1224 |
fun err msg = raise THM ("unconstrainT: " ^ msg, 0, [thm]);
|
wenzelm@36778
|
1225 |
val _ = null hyps orelse err "illegal hyps";
|
wenzelm@36778
|
1226 |
val _ = null tpairs orelse err "unsolved flex-flex constraints";
|
wenzelm@36778
|
1227 |
val tfrees = rev (Term.add_tfree_names prop []);
|
wenzelm@36778
|
1228 |
val _ = null tfrees orelse err ("illegal free type variables " ^ commas_quote tfrees);
|
wenzelm@36778
|
1229 |
|
wenzelm@42574
|
1230 |
val ps = map (apsnd (Future.map fulfill_body)) promises;
|
wenzelm@36931
|
1231 |
val thy = Theory.deref thy_ref;
|
wenzelm@37309
|
1232 |
val (pthm as (_, (_, prop', _)), proof) =
|
wenzelm@37309
|
1233 |
Proofterm.unconstrain_thm_proof thy shyps prop ps body;
|
wenzelm@36931
|
1234 |
val der' = make_deriv [] [] [pthm] proof;
|
wenzelm@36931
|
1235 |
val _ = Theory.check_thy thy;
|
wenzelm@19505
|
1236 |
in
|
wenzelm@36931
|
1237 |
Thm (der',
|
wenzelm@36778
|
1238 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1239 |
tags = [],
|
wenzelm@36778
|
1240 |
maxidx = maxidx_of_term prop',
|
wenzelm@36778
|
1241 |
shyps = [[]], (*potentially redundant*)
|
wenzelm@36931
|
1242 |
hyps = [],
|
wenzelm@36931
|
1243 |
tpairs = [],
|
wenzelm@36778
|
1244 |
prop = prop'})
|
wenzelm@19505
|
1245 |
end;
|
wenzelm@399
|
1246 |
|
wenzelm@6786
|
1247 |
(* Replace all TFrees not fixed or in the hyps by new TVars *)
|
wenzelm@35845
|
1248 |
fun varifyT_global' fixed (Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@12500
|
1249 |
let
|
wenzelm@29272
|
1250 |
val tfrees = fold Term.add_tfrees hyps fixed;
|
berghofe@13658
|
1251 |
val prop1 = attach_tpairs tpairs prop;
|
wenzelm@35845
|
1252 |
val (al, prop2) = Type.varify_global tfrees prop1;
|
wenzelm@16601
|
1253 |
val (ts, prop3) = Logic.strip_prems (length tpairs, [], prop2);
|
wenzelm@16601
|
1254 |
in
|
wenzelm@37309
|
1255 |
(al, Thm (deriv_rule1 (Proofterm.varify_proof prop tfrees) der,
|
wenzelm@28321
|
1256 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1257 |
tags = [],
|
wenzelm@16601
|
1258 |
maxidx = Int.max (0, maxidx),
|
wenzelm@16601
|
1259 |
shyps = shyps,
|
wenzelm@16601
|
1260 |
hyps = hyps,
|
wenzelm@16601
|
1261 |
tpairs = rev (map Logic.dest_equals ts),
|
wenzelm@28321
|
1262 |
prop = prop3}))
|
wenzelm@28321
|
1263 |
end;
|
wenzelm@28321
|
1264 |
|
wenzelm@35845
|
1265 |
val varifyT_global = #2 o varifyT_global' [];
|
wenzelm@28321
|
1266 |
|
wenzelm@36638
|
1267 |
(* Replace all TVars by TFrees that are often new *)
|
wenzelm@36638
|
1268 |
fun legacy_freezeT (Thm (der, {thy_ref, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@28321
|
1269 |
let
|
wenzelm@28321
|
1270 |
val prop1 = attach_tpairs tpairs prop;
|
wenzelm@33832
|
1271 |
val prop2 = Type.legacy_freeze prop1;
|
wenzelm@28321
|
1272 |
val (ts, prop3) = Logic.strip_prems (length tpairs, [], prop2);
|
wenzelm@28321
|
1273 |
in
|
wenzelm@37309
|
1274 |
Thm (deriv_rule1 (Proofterm.legacy_freezeT prop1) der,
|
wenzelm@28321
|
1275 |
{thy_ref = thy_ref,
|
wenzelm@28321
|
1276 |
tags = [],
|
wenzelm@28321
|
1277 |
maxidx = maxidx_of_term prop2,
|
wenzelm@28321
|
1278 |
shyps = shyps,
|
wenzelm@28321
|
1279 |
hyps = hyps,
|
wenzelm@28321
|
1280 |
tpairs = rev (map Logic.dest_equals ts),
|
wenzelm@18127
|
1281 |
prop = prop3})
|
clasohm@0
|
1282 |
end;
|
clasohm@0
|
1283 |
|
clasohm@0
|
1284 |
|
clasohm@0
|
1285 |
(*** Inference rules for tactics ***)
|
clasohm@0
|
1286 |
|
clasohm@0
|
1287 |
(*Destruct proof state into constraints, other goals, goal(i), rest *)
|
wenzelm@28321
|
1288 |
fun dest_state (state as Thm (_, {prop,tpairs,...}), i) =
|
berghofe@13658
|
1289 |
(case Logic.strip_prems(i, [], prop) of
|
berghofe@13658
|
1290 |
(B::rBs, C) => (tpairs, rev rBs, B, C)
|
berghofe@13658
|
1291 |
| _ => raise THM("dest_state", i, [state]))
|
clasohm@0
|
1292 |
handle TERM _ => raise THM("dest_state", i, [state]);
|
clasohm@0
|
1293 |
|
lcp@309
|
1294 |
(*Increment variables and parameters of orule as required for
|
wenzelm@18035
|
1295 |
resolution with a goal.*)
|
wenzelm@18035
|
1296 |
fun lift_rule goal orule =
|
wenzelm@16601
|
1297 |
let
|
wenzelm@18035
|
1298 |
val Cterm {t = gprop, T, maxidx = gmax, sorts, ...} = goal;
|
wenzelm@18035
|
1299 |
val inc = gmax + 1;
|
wenzelm@18035
|
1300 |
val lift_abs = Logic.lift_abs inc gprop;
|
wenzelm@18035
|
1301 |
val lift_all = Logic.lift_all inc gprop;
|
wenzelm@28321
|
1302 |
val Thm (der, {maxidx, shyps, hyps, tpairs, prop, ...}) = orule;
|
wenzelm@16601
|
1303 |
val (As, B) = Logic.strip_horn prop;
|
wenzelm@16601
|
1304 |
in
|
wenzelm@18035
|
1305 |
if T <> propT then raise THM ("lift_rule: the term must have type prop", 0, [])
|
wenzelm@18035
|
1306 |
else
|
wenzelm@37309
|
1307 |
Thm (deriv_rule1 (Proofterm.lift_proof gprop inc prop) der,
|
wenzelm@28321
|
1308 |
{thy_ref = merge_thys1 goal orule,
|
wenzelm@21646
|
1309 |
tags = [],
|
wenzelm@18035
|
1310 |
maxidx = maxidx + inc,
|
wenzelm@18035
|
1311 |
shyps = Sorts.union shyps sorts, (*sic!*)
|
wenzelm@18035
|
1312 |
hyps = hyps,
|
wenzelm@18035
|
1313 |
tpairs = map (pairself lift_abs) tpairs,
|
wenzelm@28321
|
1314 |
prop = Logic.list_implies (map lift_all As, lift_all B)})
|
clasohm@0
|
1315 |
end;
|
clasohm@0
|
1316 |
|
wenzelm@28321
|
1317 |
fun incr_indexes i (thm as Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
|
wenzelm@16601
|
1318 |
if i < 0 then raise THM ("negative increment", 0, [thm])
|
wenzelm@16601
|
1319 |
else if i = 0 then thm
|
wenzelm@16601
|
1320 |
else
|
wenzelm@37309
|
1321 |
Thm (deriv_rule1 (Proofterm.incr_indexes i) der,
|
wenzelm@28321
|
1322 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1323 |
tags = [],
|
wenzelm@16601
|
1324 |
maxidx = maxidx + i,
|
wenzelm@16601
|
1325 |
shyps = shyps,
|
wenzelm@16601
|
1326 |
hyps = hyps,
|
wenzelm@16601
|
1327 |
tpairs = map (pairself (Logic.incr_indexes ([], i))) tpairs,
|
wenzelm@28321
|
1328 |
prop = Logic.incr_indexes ([], i) prop});
|
berghofe@10416
|
1329 |
|
clasohm@0
|
1330 |
(*Solve subgoal Bi of proof state B1...Bn/C by assumption. *)
|
clasohm@0
|
1331 |
fun assumption i state =
|
wenzelm@16601
|
1332 |
let
|
wenzelm@32791
|
1333 |
val Thm (der, {thy_ref, maxidx, shyps, hyps, ...}) = state;
|
wenzelm@16656
|
1334 |
val thy = Theory.deref thy_ref;
|
wenzelm@16601
|
1335 |
val (tpairs, Bs, Bi, C) = dest_state (state, i);
|
wenzelm@32043
|
1336 |
fun newth n (env, tpairs) =
|
wenzelm@28321
|
1337 |
Thm (deriv_rule1
|
wenzelm@37309
|
1338 |
((if Envir.is_empty env then I else (Proofterm.norm_proof' env)) o
|
wenzelm@37309
|
1339 |
Proofterm.assumption_proof Bs Bi n) der,
|
wenzelm@28321
|
1340 |
{tags = [],
|
wenzelm@32043
|
1341 |
maxidx = Envir.maxidx_of env,
|
wenzelm@26640
|
1342 |
shyps = Envir.insert_sorts env shyps,
|
wenzelm@16601
|
1343 |
hyps = hyps,
|
wenzelm@16601
|
1344 |
tpairs =
|
wenzelm@16601
|
1345 |
if Envir.is_empty env then tpairs
|
wenzelm@16601
|
1346 |
else map (pairself (Envir.norm_term env)) tpairs,
|
wenzelm@16601
|
1347 |
prop =
|
wenzelm@16601
|
1348 |
if Envir.is_empty env then (*avoid wasted normalizations*)
|
wenzelm@16601
|
1349 |
Logic.list_implies (Bs, C)
|
wenzelm@16601
|
1350 |
else (*normalize the new rule fully*)
|
wenzelm@24143
|
1351 |
Envir.norm_term env (Logic.list_implies (Bs, C)),
|
wenzelm@28321
|
1352 |
thy_ref = Theory.check_thy thy});
|
wenzelm@30556
|
1353 |
|
wenzelm@30558
|
1354 |
val (close, asms, concl) = Logic.assum_problems (~1, Bi);
|
wenzelm@30558
|
1355 |
val concl' = close concl;
|
wenzelm@16601
|
1356 |
fun addprfs [] _ = Seq.empty
|
wenzelm@30558
|
1357 |
| addprfs (asm :: rest) n = Seq.make (fn () => Seq.pull
|
wenzelm@16601
|
1358 |
(Seq.mapp (newth n)
|
wenzelm@30558
|
1359 |
(if Term.could_unify (asm, concl) then
|
wenzelm@30558
|
1360 |
(Unify.unifiers (thy, Envir.empty maxidx, (close asm, concl') :: tpairs))
|
wenzelm@30556
|
1361 |
else Seq.empty)
|
wenzelm@30556
|
1362 |
(addprfs rest (n + 1))))
|
wenzelm@30558
|
1363 |
in addprfs asms 1 end;
|
clasohm@0
|
1364 |
|
wenzelm@250
|
1365 |
(*Solve subgoal Bi of proof state B1...Bn/C by assumption.
|
clasohm@0
|
1366 |
Checks if Bi's conclusion is alpha-convertible to one of its assumptions*)
|
clasohm@0
|
1367 |
fun eq_assumption i state =
|
wenzelm@16601
|
1368 |
let
|
wenzelm@32791
|
1369 |
val Thm (der, {thy_ref, maxidx, shyps, hyps, ...}) = state;
|
wenzelm@16601
|
1370 |
val (tpairs, Bs, Bi, C) = dest_state (state, i);
|
wenzelm@30558
|
1371 |
val (_, asms, concl) = Logic.assum_problems (~1, Bi);
|
wenzelm@16601
|
1372 |
in
|
wenzelm@30558
|
1373 |
(case find_index (fn asm => Pattern.aeconv (asm, concl)) asms of
|
wenzelm@16601
|
1374 |
~1 => raise THM ("eq_assumption", 0, [state])
|
wenzelm@16601
|
1375 |
| n =>
|
wenzelm@37309
|
1376 |
Thm (deriv_rule1 (Proofterm.assumption_proof Bs Bi (n + 1)) der,
|
wenzelm@28321
|
1377 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1378 |
tags = [],
|
wenzelm@16425
|
1379 |
maxidx = maxidx,
|
wenzelm@16425
|
1380 |
shyps = shyps,
|
wenzelm@16425
|
1381 |
hyps = hyps,
|
berghofe@13658
|
1382 |
tpairs = tpairs,
|
wenzelm@28321
|
1383 |
prop = Logic.list_implies (Bs, C)}))
|
wenzelm@16601
|
1384 |
end;
|
wenzelm@16601
|
1385 |
|
wenzelm@16601
|
1386 |
|
wenzelm@16601
|
1387 |
(*For rotate_tac: fast rotation of assumptions of subgoal i*)
|
wenzelm@16601
|
1388 |
fun rotate_rule k i state =
|
wenzelm@16601
|
1389 |
let
|
wenzelm@32791
|
1390 |
val Thm (der, {thy_ref, maxidx, shyps, hyps, ...}) = state;
|
wenzelm@16601
|
1391 |
val (tpairs, Bs, Bi, C) = dest_state (state, i);
|
wenzelm@16601
|
1392 |
val params = Term.strip_all_vars Bi
|
wenzelm@16601
|
1393 |
and rest = Term.strip_all_body Bi;
|
wenzelm@16601
|
1394 |
val asms = Logic.strip_imp_prems rest
|
wenzelm@16601
|
1395 |
and concl = Logic.strip_imp_concl rest;
|
wenzelm@16601
|
1396 |
val n = length asms;
|
wenzelm@16601
|
1397 |
val m = if k < 0 then n + k else k;
|
wenzelm@16601
|
1398 |
val Bi' =
|
wenzelm@16601
|
1399 |
if 0 = m orelse m = n then Bi
|
wenzelm@16601
|
1400 |
else if 0 < m andalso m < n then
|
wenzelm@19012
|
1401 |
let val (ps, qs) = chop m asms
|
wenzelm@16601
|
1402 |
in list_all (params, Logic.list_implies (qs @ ps, concl)) end
|
wenzelm@16601
|
1403 |
else raise THM ("rotate_rule", k, [state]);
|
wenzelm@16601
|
1404 |
in
|
wenzelm@37309
|
1405 |
Thm (deriv_rule1 (Proofterm.rotate_proof Bs Bi m) der,
|
wenzelm@28321
|
1406 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1407 |
tags = [],
|
wenzelm@16601
|
1408 |
maxidx = maxidx,
|
wenzelm@16601
|
1409 |
shyps = shyps,
|
wenzelm@16601
|
1410 |
hyps = hyps,
|
wenzelm@16601
|
1411 |
tpairs = tpairs,
|
wenzelm@28321
|
1412 |
prop = Logic.list_implies (Bs @ [Bi'], C)})
|
paulson@2671
|
1413 |
end;
|
paulson@2671
|
1414 |
|
paulson@2671
|
1415 |
|
paulson@7248
|
1416 |
(*Rotates a rule's premises to the left by k, leaving the first j premises
|
paulson@7248
|
1417 |
unchanged. Does nothing if k=0 or if k equals n-j, where n is the
|
wenzelm@16656
|
1418 |
number of premises. Useful with etac and underlies defer_tac*)
|
paulson@7248
|
1419 |
fun permute_prems j k rl =
|
wenzelm@16601
|
1420 |
let
|
wenzelm@28321
|
1421 |
val Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...}) = rl;
|
wenzelm@16601
|
1422 |
val prems = Logic.strip_imp_prems prop
|
wenzelm@16601
|
1423 |
and concl = Logic.strip_imp_concl prop;
|
wenzelm@16601
|
1424 |
val moved_prems = List.drop (prems, j)
|
wenzelm@16601
|
1425 |
and fixed_prems = List.take (prems, j)
|
wenzelm@44158
|
1426 |
handle General.Subscript => raise THM ("permute_prems: j", j, [rl]);
|
wenzelm@16601
|
1427 |
val n_j = length moved_prems;
|
wenzelm@16601
|
1428 |
val m = if k < 0 then n_j + k else k;
|
wenzelm@16601
|
1429 |
val prop' =
|
wenzelm@16601
|
1430 |
if 0 = m orelse m = n_j then prop
|
wenzelm@16601
|
1431 |
else if 0 < m andalso m < n_j then
|
wenzelm@19012
|
1432 |
let val (ps, qs) = chop m moved_prems
|
wenzelm@16601
|
1433 |
in Logic.list_implies (fixed_prems @ qs @ ps, concl) end
|
wenzelm@16725
|
1434 |
else raise THM ("permute_prems: k", k, [rl]);
|
wenzelm@16601
|
1435 |
in
|
wenzelm@37309
|
1436 |
Thm (deriv_rule1 (Proofterm.permute_prems_proof prems j m) der,
|
wenzelm@28321
|
1437 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1438 |
tags = [],
|
wenzelm@16601
|
1439 |
maxidx = maxidx,
|
wenzelm@16601
|
1440 |
shyps = shyps,
|
wenzelm@16601
|
1441 |
hyps = hyps,
|
wenzelm@16601
|
1442 |
tpairs = tpairs,
|
wenzelm@28321
|
1443 |
prop = prop'})
|
paulson@7248
|
1444 |
end;
|
paulson@7248
|
1445 |
|
paulson@7248
|
1446 |
|
clasohm@0
|
1447 |
(** User renaming of parameters in a subgoal **)
|
clasohm@0
|
1448 |
|
clasohm@0
|
1449 |
(*Calls error rather than raising an exception because it is intended
|
clasohm@0
|
1450 |
for top-level use -- exception handling would not make sense here.
|
clasohm@0
|
1451 |
The names in cs, if distinct, are used for the innermost parameters;
|
wenzelm@17868
|
1452 |
preceding parameters may be renamed to make all params distinct.*)
|
clasohm@0
|
1453 |
fun rename_params_rule (cs, i) state =
|
wenzelm@16601
|
1454 |
let
|
wenzelm@28321
|
1455 |
val Thm (der, {thy_ref, tags, maxidx, shyps, hyps, ...}) = state;
|
wenzelm@16601
|
1456 |
val (tpairs, Bs, Bi, C) = dest_state (state, i);
|
wenzelm@16601
|
1457 |
val iparams = map #1 (Logic.strip_params Bi);
|
wenzelm@16601
|
1458 |
val short = length iparams - length cs;
|
wenzelm@16601
|
1459 |
val newnames =
|
wenzelm@16601
|
1460 |
if short < 0 then error "More names than abstractions!"
|
haftmann@33956
|
1461 |
else Name.variant_list cs (take short iparams) @ cs;
|
wenzelm@20330
|
1462 |
val freenames = Term.fold_aterms (fn Free (x, _) => insert (op =) x | _ => I) Bi [];
|
wenzelm@16601
|
1463 |
val newBi = Logic.list_rename_params (newnames, Bi);
|
wenzelm@250
|
1464 |
in
|
wenzelm@21182
|
1465 |
(case duplicates (op =) cs of
|
wenzelm@21182
|
1466 |
a :: _ => (warning ("Can't rename. Bound variables not distinct: " ^ a); state)
|
wenzelm@21182
|
1467 |
| [] =>
|
haftmann@33049
|
1468 |
(case inter (op =) cs freenames of
|
wenzelm@16601
|
1469 |
a :: _ => (warning ("Can't rename. Bound/Free variable clash: " ^ a); state)
|
wenzelm@16601
|
1470 |
| [] =>
|
wenzelm@28321
|
1471 |
Thm (der,
|
wenzelm@28321
|
1472 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1473 |
tags = tags,
|
wenzelm@16601
|
1474 |
maxidx = maxidx,
|
wenzelm@16601
|
1475 |
shyps = shyps,
|
wenzelm@16601
|
1476 |
hyps = hyps,
|
wenzelm@16601
|
1477 |
tpairs = tpairs,
|
wenzelm@28321
|
1478 |
prop = Logic.list_implies (Bs @ [newBi], C)})))
|
clasohm@0
|
1479 |
end;
|
clasohm@0
|
1480 |
|
wenzelm@12982
|
1481 |
|
clasohm@0
|
1482 |
(*** Preservation of bound variable names ***)
|
clasohm@0
|
1483 |
|
wenzelm@28321
|
1484 |
fun rename_boundvars pat obj (thm as Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
|
wenzelm@12982
|
1485 |
(case Term.rename_abs pat obj prop of
|
skalberg@15531
|
1486 |
NONE => thm
|
wenzelm@28321
|
1487 |
| SOME prop' => Thm (der,
|
wenzelm@16425
|
1488 |
{thy_ref = thy_ref,
|
wenzelm@21646
|
1489 |
tags = tags,
|
wenzelm@12982
|
1490 |
maxidx = maxidx,
|
wenzelm@12982
|
1491 |
hyps = hyps,
|
wenzelm@12982
|
1492 |
shyps = shyps,
|
berghofe@13658
|
1493 |
tpairs = tpairs,
|
wenzelm@28321
|
1494 |
prop = prop'}));
|
berghofe@10416
|
1495 |
|
clasohm@0
|
1496 |
|
wenzelm@16656
|
1497 |
(* strip_apply f (A, B) strips off all assumptions/parameters from A
|
clasohm@0
|
1498 |
introduced by lifting over B, and applies f to remaining part of A*)
|
clasohm@0
|
1499 |
fun strip_apply f =
|
clasohm@0
|
1500 |
let fun strip(Const("==>",_)$ A1 $ B1,
|
wenzelm@27336
|
1501 |
Const("==>",_)$ _ $ B2) = Logic.mk_implies (A1, strip(B1,B2))
|
wenzelm@250
|
1502 |
| strip((c as Const("all",_)) $ Abs(a,T,t1),
|
wenzelm@250
|
1503 |
Const("all",_) $ Abs(_,_,t2)) = c$Abs(a,T,strip(t1,t2))
|
wenzelm@250
|
1504 |
| strip(A,_) = f A
|
clasohm@0
|
1505 |
in strip end;
|
clasohm@0
|
1506 |
|
clasohm@0
|
1507 |
(*Use the alist to rename all bound variables and some unknowns in a term
|
clasohm@0
|
1508 |
dpairs = current disagreement pairs; tpairs = permanent ones (flexflex);
|
clasohm@0
|
1509 |
Preserves unknowns in tpairs and on lhs of dpairs. *)
|
clasohm@0
|
1510 |
fun rename_bvs([],_,_,_) = I
|
clasohm@0
|
1511 |
| rename_bvs(al,dpairs,tpairs,B) =
|
wenzelm@20330
|
1512 |
let
|
wenzelm@20330
|
1513 |
val add_var = fold_aterms (fn Var ((x, _), _) => insert (op =) x | _ => I);
|
wenzelm@20330
|
1514 |
val vids = []
|
wenzelm@20330
|
1515 |
|> fold (add_var o fst) dpairs
|
wenzelm@20330
|
1516 |
|> fold (add_var o fst) tpairs
|
wenzelm@20330
|
1517 |
|> fold (add_var o snd) tpairs;
|
wenzelm@250
|
1518 |
(*unknowns appearing elsewhere be preserved!*)
|
wenzelm@250
|
1519 |
fun rename(t as Var((x,i),T)) =
|
wenzelm@20330
|
1520 |
(case AList.lookup (op =) al x of
|
wenzelm@20330
|
1521 |
SOME y =>
|
wenzelm@20330
|
1522 |
if member (op =) vids x orelse member (op =) vids y then t
|
wenzelm@20330
|
1523 |
else Var((y,i),T)
|
wenzelm@20330
|
1524 |
| NONE=> t)
|
clasohm@0
|
1525 |
| rename(Abs(x,T,t)) =
|
wenzelm@18944
|
1526 |
Abs (the_default x (AList.lookup (op =) al x), T, rename t)
|
clasohm@0
|
1527 |
| rename(f$t) = rename f $ rename t
|
clasohm@0
|
1528 |
| rename(t) = t;
|
wenzelm@250
|
1529 |
fun strip_ren Ai = strip_apply rename (Ai,B)
|
wenzelm@20330
|
1530 |
in strip_ren end;
|
clasohm@0
|
1531 |
|
clasohm@0
|
1532 |
(*Function to rename bounds/unknowns in the argument, lifted over B*)
|
clasohm@0
|
1533 |
fun rename_bvars(dpairs, tpairs, B) =
|
wenzelm@23178
|
1534 |
rename_bvs(List.foldr Term.match_bvars [] dpairs, dpairs, tpairs, B);
|
clasohm@0
|
1535 |
|
clasohm@0
|
1536 |
|
clasohm@0
|
1537 |
(*** RESOLUTION ***)
|
clasohm@0
|
1538 |
|
lcp@721
|
1539 |
(** Lifting optimizations **)
|
lcp@721
|
1540 |
|
clasohm@0
|
1541 |
(*strip off pairs of assumptions/parameters in parallel -- they are
|
clasohm@0
|
1542 |
identical because of lifting*)
|
wenzelm@250
|
1543 |
fun strip_assums2 (Const("==>", _) $ _ $ B1,
|
wenzelm@250
|
1544 |
Const("==>", _) $ _ $ B2) = strip_assums2 (B1,B2)
|
clasohm@0
|
1545 |
| strip_assums2 (Const("all",_)$Abs(a,T,t1),
|
wenzelm@250
|
1546 |
Const("all",_)$Abs(_,_,t2)) =
|
clasohm@0
|
1547 |
let val (B1,B2) = strip_assums2 (t1,t2)
|
clasohm@0
|
1548 |
in (Abs(a,T,B1), Abs(a,T,B2)) end
|
clasohm@0
|
1549 |
| strip_assums2 BB = BB;
|
clasohm@0
|
1550 |
|
clasohm@0
|
1551 |
|
lcp@721
|
1552 |
(*Faster normalization: skip assumptions that were lifted over*)
|
lcp@721
|
1553 |
fun norm_term_skip env 0 t = Envir.norm_term env t
|
wenzelm@32043
|
1554 |
| norm_term_skip env n (Const ("all", _) $ Abs (a, T, t)) =
|
wenzelm@32043
|
1555 |
let
|
wenzelm@32046
|
1556 |
val T' = Envir.subst_type (Envir.type_env env) T
|
wenzelm@32043
|
1557 |
(*Must instantiate types of parameters because they are flattened;
|
wenzelm@32043
|
1558 |
this could be a NEW parameter*)
|
wenzelm@32043
|
1559 |
in Term.all T' $ Abs (a, T', norm_term_skip env n t) end
|
wenzelm@32043
|
1560 |
| norm_term_skip env n (Const ("==>", _) $ A $ B) =
|
wenzelm@32043
|
1561 |
Logic.mk_implies (A, norm_term_skip env (n - 1) B)
|
wenzelm@32791
|
1562 |
| norm_term_skip _ _ _ = error "norm_term_skip: too few assumptions??";
|
lcp@721
|
1563 |
|
lcp@721
|
1564 |
|
clasohm@0
|
1565 |
(*Composition of object rule r=(A1...Am/B) with proof state s=(B1...Bn/C)
|
wenzelm@250
|
1566 |
Unifies B with Bi, replacing subgoal i (1 <= i <= n)
|
clasohm@0
|
1567 |
If match then forbid instantiations in proof state
|
clasohm@0
|
1568 |
If lifted then shorten the dpair using strip_assums2.
|
clasohm@0
|
1569 |
If eres_flg then simultaneously proves A1 by assumption.
|
wenzelm@250
|
1570 |
nsubgoal is the number of new subgoals (written m above).
|
clasohm@0
|
1571 |
Curried so that resolution calls dest_state only once.
|
clasohm@0
|
1572 |
*)
|
wenzelm@4270
|
1573 |
local exception COMPOSE
|
clasohm@0
|
1574 |
in
|
wenzelm@18486
|
1575 |
fun bicompose_aux flatten match (state, (stpairs, Bs, Bi, C), lifted)
|
clasohm@0
|
1576 |
(eres_flg, orule, nsubgoal) =
|
wenzelm@28321
|
1577 |
let val Thm (sder, {maxidx=smax, shyps=sshyps, hyps=shyps, ...}) = state
|
wenzelm@28321
|
1578 |
and Thm (rder, {maxidx=rmax, shyps=rshyps, hyps=rhyps,
|
wenzelm@28321
|
1579 |
tpairs=rtpairs, prop=rprop,...}) = orule
|
paulson@1529
|
1580 |
(*How many hyps to skip over during normalization*)
|
wenzelm@21576
|
1581 |
and nlift = Logic.count_prems (strip_all_body Bi) + (if eres_flg then ~1 else 0)
|
wenzelm@24143
|
1582 |
val thy = Theory.deref (merge_thys2 state orule);
|
clasohm@0
|
1583 |
(** Add new theorem with prop = '[| Bs; As |] ==> C' to thq **)
|
wenzelm@32043
|
1584 |
fun addth A (As, oldAs, rder', n) ((env, tpairs), thq) =
|
wenzelm@250
|
1585 |
let val normt = Envir.norm_term env;
|
wenzelm@250
|
1586 |
(*perform minimal copying here by examining env*)
|
berghofe@13658
|
1587 |
val (ntpairs, normp) =
|
berghofe@13658
|
1588 |
if Envir.is_empty env then (tpairs, (Bs @ As, C))
|
wenzelm@250
|
1589 |
else
|
wenzelm@250
|
1590 |
let val ntps = map (pairself normt) tpairs
|
wenzelm@19861
|
1591 |
in if Envir.above env smax then
|
wenzelm@1238
|
1592 |
(*no assignments in state; normalize the rule only*)
|
wenzelm@1238
|
1593 |
if lifted
|
berghofe@13658
|
1594 |
then (ntps, (Bs @ map (norm_term_skip env nlift) As, C))
|
berghofe@13658
|
1595 |
else (ntps, (Bs @ map normt As, C))
|
paulson@1529
|
1596 |
else if match then raise COMPOSE
|
wenzelm@250
|
1597 |
else (*normalize the new rule fully*)
|
berghofe@13658
|
1598 |
(ntps, (map normt (Bs @ As), normt C))
|
wenzelm@250
|
1599 |
end
|
wenzelm@16601
|
1600 |
val th =
|
wenzelm@28321
|
1601 |
Thm (deriv_rule2
|
berghofe@11518
|
1602 |
((if Envir.is_empty env then I
|
wenzelm@19861
|
1603 |
else if Envir.above env smax then
|
wenzelm@37309
|
1604 |
(fn f => fn der => f (Proofterm.norm_proof' env der))
|
berghofe@11518
|
1605 |
else
|
wenzelm@37309
|
1606 |
curry op oo (Proofterm.norm_proof' env))
|
wenzelm@37309
|
1607 |
(Proofterm.bicompose_proof flatten Bs oldAs As A n (nlift+1))) rder' sder,
|
wenzelm@28321
|
1608 |
{tags = [],
|
wenzelm@32043
|
1609 |
maxidx = Envir.maxidx_of env,
|
wenzelm@26640
|
1610 |
shyps = Envir.insert_sorts env (Sorts.union rshyps sshyps),
|
wenzelm@16601
|
1611 |
hyps = union_hyps rhyps shyps,
|
berghofe@13658
|
1612 |
tpairs = ntpairs,
|
wenzelm@24143
|
1613 |
prop = Logic.list_implies normp,
|
wenzelm@28321
|
1614 |
thy_ref = Theory.check_thy thy})
|
wenzelm@19475
|
1615 |
in Seq.cons th thq end handle COMPOSE => thq;
|
berghofe@13658
|
1616 |
val (rAs,B) = Logic.strip_prems(nsubgoal, [], rprop)
|
clasohm@0
|
1617 |
handle TERM _ => raise THM("bicompose: rule", 0, [orule,state]);
|
clasohm@0
|
1618 |
(*Modify assumptions, deleting n-th if n>0 for e-resolution*)
|
clasohm@0
|
1619 |
fun newAs(As0, n, dpairs, tpairs) =
|
berghofe@11518
|
1620 |
let val (As1, rder') =
|
berghofe@25939
|
1621 |
if not lifted then (As0, rder)
|
berghofe@11518
|
1622 |
else (map (rename_bvars(dpairs,tpairs,B)) As0,
|
wenzelm@37309
|
1623 |
deriv_rule1 (Proofterm.map_proof_terms
|
berghofe@11518
|
1624 |
(rename_bvars (dpairs, tpairs, Bound 0)) I) rder);
|
wenzelm@18486
|
1625 |
in (map (if flatten then (Logic.flatten_params n) else I) As1, As1, rder', n)
|
wenzelm@250
|
1626 |
handle TERM _ =>
|
wenzelm@250
|
1627 |
raise THM("bicompose: 1st premise", 0, [orule])
|
clasohm@0
|
1628 |
end;
|
paulson@2147
|
1629 |
val env = Envir.empty(Int.max(rmax,smax));
|
clasohm@0
|
1630 |
val BBi = if lifted then strip_assums2(B,Bi) else (B,Bi);
|
clasohm@0
|
1631 |
val dpairs = BBi :: (rtpairs@stpairs);
|
wenzelm@30556
|
1632 |
|
wenzelm@30556
|
1633 |
(*elim-resolution: try each assumption in turn*)
|
wenzelm@30556
|
1634 |
fun eres [] = raise THM ("bicompose: no premises", 0, [orule, state])
|
wenzelm@30556
|
1635 |
| eres (A1 :: As) =
|
wenzelm@30556
|
1636 |
let
|
wenzelm@30556
|
1637 |
val A = SOME A1;
|
wenzelm@30558
|
1638 |
val (close, asms, concl) = Logic.assum_problems (nlift + 1, A1);
|
wenzelm@30558
|
1639 |
val concl' = close concl;
|
wenzelm@30556
|
1640 |
fun tryasms [] _ = Seq.empty
|
wenzelm@30558
|
1641 |
| tryasms (asm :: rest) n =
|
wenzelm@30558
|
1642 |
if Term.could_unify (asm, concl) then
|
wenzelm@30558
|
1643 |
let val asm' = close asm in
|
wenzelm@30558
|
1644 |
(case Seq.pull (Unify.unifiers (thy, env, (asm', concl') :: dpairs)) of
|
wenzelm@30556
|
1645 |
NONE => tryasms rest (n + 1)
|
wenzelm@30556
|
1646 |
| cell as SOME ((_, tpairs), _) =>
|
wenzelm@30558
|
1647 |
Seq.it_right (addth A (newAs (As, n, [BBi, (concl', asm')], tpairs)))
|
wenzelm@30556
|
1648 |
(Seq.make (fn () => cell),
|
wenzelm@30556
|
1649 |
Seq.make (fn () => Seq.pull (tryasms rest (n + 1)))))
|
wenzelm@30556
|
1650 |
end
|
wenzelm@30556
|
1651 |
else tryasms rest (n + 1);
|
wenzelm@30558
|
1652 |
in tryasms asms 1 end;
|
wenzelm@30556
|
1653 |
|
clasohm@0
|
1654 |
(*ordinary resolution*)
|
wenzelm@30556
|
1655 |
fun res () =
|
wenzelm@30556
|
1656 |
(case Seq.pull (Unify.unifiers (thy, env, dpairs)) of
|
wenzelm@30556
|
1657 |
NONE => Seq.empty
|
wenzelm@30556
|
1658 |
| cell as SOME ((_, tpairs), _) =>
|
wenzelm@30556
|
1659 |
Seq.it_right (addth NONE (newAs (rev rAs, 0, [BBi], tpairs)))
|
wenzelm@30556
|
1660 |
(Seq.make (fn () => cell), Seq.empty));
|
wenzelm@30556
|
1661 |
in
|
wenzelm@30556
|
1662 |
if eres_flg then eres (rev rAs) else res ()
|
clasohm@0
|
1663 |
end;
|
wenzelm@7528
|
1664 |
end;
|
clasohm@0
|
1665 |
|
wenzelm@18501
|
1666 |
fun compose_no_flatten match (orule, nsubgoal) i state =
|
wenzelm@18501
|
1667 |
bicompose_aux false match (state, dest_state (state, i), false) (false, orule, nsubgoal);
|
clasohm@0
|
1668 |
|
wenzelm@18501
|
1669 |
fun bicompose match arg i state =
|
wenzelm@18501
|
1670 |
bicompose_aux true match (state, dest_state (state,i), false) arg;
|
clasohm@0
|
1671 |
|
clasohm@0
|
1672 |
(*Quick test whether rule is resolvable with the subgoal with hyps Hs
|
clasohm@0
|
1673 |
and conclusion B. If eres_flg then checks 1st premise of rule also*)
|
clasohm@0
|
1674 |
fun could_bires (Hs, B, eres_flg, rule) =
|
wenzelm@29269
|
1675 |
let fun could_reshyp (A1::_) = exists (fn H => Term.could_unify (A1, H)) Hs
|
wenzelm@250
|
1676 |
| could_reshyp [] = false; (*no premise -- illegal*)
|
wenzelm@29269
|
1677 |
in Term.could_unify(concl_of rule, B) andalso
|
wenzelm@250
|
1678 |
(not eres_flg orelse could_reshyp (prems_of rule))
|
clasohm@0
|
1679 |
end;
|
clasohm@0
|
1680 |
|
clasohm@0
|
1681 |
(*Bi-resolution of a state with a list of (flag,rule) pairs.
|
clasohm@0
|
1682 |
Puts the rule above: rule/state. Renames vars in the rules. *)
|
wenzelm@250
|
1683 |
fun biresolution match brules i state =
|
wenzelm@18035
|
1684 |
let val (stpairs, Bs, Bi, C) = dest_state(state,i);
|
wenzelm@18145
|
1685 |
val lift = lift_rule (cprem_of state i);
|
wenzelm@250
|
1686 |
val B = Logic.strip_assums_concl Bi;
|
wenzelm@250
|
1687 |
val Hs = Logic.strip_assums_hyp Bi;
|
wenzelm@22573
|
1688 |
val compose = bicompose_aux true match (state, (stpairs, Bs, Bi, C), true);
|
wenzelm@4270
|
1689 |
fun res [] = Seq.empty
|
wenzelm@250
|
1690 |
| res ((eres_flg, rule)::brules) =
|
nipkow@13642
|
1691 |
if !Pattern.trace_unify_fail orelse
|
nipkow@13642
|
1692 |
could_bires (Hs, B, eres_flg, rule)
|
wenzelm@4270
|
1693 |
then Seq.make (*delay processing remainder till needed*)
|
wenzelm@22573
|
1694 |
(fn()=> SOME(compose (eres_flg, lift rule, nprems_of rule),
|
wenzelm@250
|
1695 |
res brules))
|
wenzelm@250
|
1696 |
else res brules
|
wenzelm@4270
|
1697 |
in Seq.flat (res brules) end;
|
clasohm@0
|
1698 |
|
clasohm@0
|
1699 |
|
wenzelm@28321
|
1700 |
|
wenzelm@2509
|
1701 |
(*** Oracles ***)
|
wenzelm@2509
|
1702 |
|
wenzelm@28290
|
1703 |
(* oracle rule *)
|
wenzelm@28290
|
1704 |
|
wenzelm@28290
|
1705 |
fun invoke_oracle thy_ref1 name oracle arg =
|
wenzelm@28624
|
1706 |
let val Cterm {thy_ref = thy_ref2, t = prop, T, maxidx, sorts} = oracle arg in
|
wenzelm@28290
|
1707 |
if T <> propT then
|
wenzelm@28290
|
1708 |
raise THM ("Oracle's result must have type prop: " ^ name, 0, [])
|
wenzelm@28290
|
1709 |
else
|
wenzelm@37309
|
1710 |
let val (ora, prf) = Proofterm.oracle_proof name prop in
|
wenzelm@32075
|
1711 |
Thm (make_deriv [] [ora] [] prf,
|
wenzelm@28804
|
1712 |
{thy_ref = Theory.merge_refs (thy_ref1, thy_ref2),
|
wenzelm@28804
|
1713 |
tags = [],
|
wenzelm@28804
|
1714 |
maxidx = maxidx,
|
wenzelm@28804
|
1715 |
shyps = sorts,
|
wenzelm@28804
|
1716 |
hyps = [],
|
wenzelm@28804
|
1717 |
tpairs = [],
|
wenzelm@28804
|
1718 |
prop = prop})
|
wenzelm@28804
|
1719 |
end
|
wenzelm@3812
|
1720 |
end;
|
wenzelm@3812
|
1721 |
|
wenzelm@32590
|
1722 |
end;
|
wenzelm@32590
|
1723 |
end;
|
wenzelm@32590
|
1724 |
end;
|
wenzelm@32590
|
1725 |
|
wenzelm@22237
|
1726 |
|
wenzelm@28290
|
1727 |
(* authentic derivation names *)
|
wenzelm@28290
|
1728 |
|
wenzelm@33522
|
1729 |
structure Oracles = Theory_Data
|
wenzelm@28290
|
1730 |
(
|
wenzelm@33100
|
1731 |
type T = unit Name_Space.table;
|
wenzelm@33157
|
1732 |
val empty : T = Name_Space.empty_table "oracle";
|
wenzelm@28290
|
1733 |
val extend = I;
|
wenzelm@33522
|
1734 |
fun merge data : T = Name_Space.merge_tables data;
|
wenzelm@28290
|
1735 |
);
|
wenzelm@28290
|
1736 |
|
wenzelm@43229
|
1737 |
fun extern_oracles ctxt =
|
wenzelm@43231
|
1738 |
map #1 (Name_Space.extern_table ctxt (Oracles.get (Proof_Context.theory_of ctxt)));
|
wenzelm@28290
|
1739 |
|
wenzelm@30288
|
1740 |
fun add_oracle (b, oracle) thy =
|
wenzelm@28290
|
1741 |
let
|
wenzelm@28290
|
1742 |
val naming = Sign.naming_of thy;
|
wenzelm@43246
|
1743 |
val (name, tab') =
|
wenzelm@43246
|
1744 |
Name_Space.define (Proof_Context.init_global thy) true naming (b, ()) (Oracles.get thy);
|
wenzelm@30288
|
1745 |
val thy' = Oracles.put tab' thy;
|
wenzelm@28290
|
1746 |
in ((name, invoke_oracle (Theory.check_thy thy') name oracle), thy') end;
|
wenzelm@28290
|
1747 |
|
clasohm@0
|
1748 |
end;
|
paulson@1503
|
1749 |
|
wenzelm@32124
|
1750 |
structure Basic_Thm: BASIC_THM = Thm;
|
wenzelm@32124
|
1751 |
open Basic_Thm;
|