2 Author: Amine Chaieb, TU Muenchen |
2 Author: Amine Chaieb, TU Muenchen |
3 |
3 |
4 Normalization of expressions in semirings. |
4 Normalization of expressions in semirings. |
5 *) |
5 *) |
6 |
6 |
7 signature SEMIRING_NORMALIZER = |
7 signature SEMIRING_NORMALIZER = |
8 sig |
8 sig |
9 type entry |
9 type entry |
10 val match: Proof.context -> cterm -> entry option |
10 val match: Proof.context -> cterm -> entry option |
11 val the_semiring: Proof.context -> thm -> cterm list * thm list |
11 val the_semiring: Proof.context -> thm -> cterm list * thm list |
12 val the_ring: Proof.context -> thm -> cterm list * thm list |
12 val the_ring: Proof.context -> thm -> cterm list * thm list |
13 val the_field: Proof.context -> thm -> cterm list * thm list |
13 val the_field: Proof.context -> thm -> cterm list * thm list |
14 val the_idom: Proof.context -> thm -> thm list |
14 val the_idom: Proof.context -> thm -> thm list |
15 val the_ideal: Proof.context -> thm -> thm list |
15 val the_ideal: Proof.context -> thm -> thm list |
16 val declare: thm -> {semiring: cterm list * thm list, ring: cterm list * thm list, |
16 val declare: thm -> {semiring: term list * thm list, ring: term list * thm list, |
17 field: cterm list * thm list, idom: thm list, ideal: thm list} -> declaration |
17 field: term list * thm list, idom: thm list, ideal: thm list} -> |
|
18 local_theory -> local_theory |
18 |
19 |
19 val semiring_normalize_conv: Proof.context -> conv |
20 val semiring_normalize_conv: Proof.context -> conv |
20 val semiring_normalize_ord_conv: Proof.context -> (cterm -> cterm -> bool) -> conv |
21 val semiring_normalize_ord_conv: Proof.context -> (cterm -> cterm -> bool) -> conv |
21 val semiring_normalize_wrapper: Proof.context -> entry -> conv |
22 val semiring_normalize_wrapper: Proof.context -> entry -> conv |
22 val semiring_normalize_ord_wrapper: Proof.context -> entry |
23 val semiring_normalize_ord_wrapper: Proof.context -> entry |
135 | Const (@{const_name Fields.inverse},_)$t => can HOLogic.dest_number t |
136 | Const (@{const_name Fields.inverse},_)$t => can HOLogic.dest_number t |
136 | t => can HOLogic.dest_number t |
137 | t => can HOLogic.dest_number t |
137 fun dest_const ct = ((case Thm.term_of ct of |
138 fun dest_const ct = ((case Thm.term_of ct of |
138 Const (@{const_name Rings.divide},_) $ a $ b=> |
139 Const (@{const_name Rings.divide},_) $ a $ b=> |
139 Rat.rat_of_quotient (snd (HOLogic.dest_number a), snd (HOLogic.dest_number b)) |
140 Rat.rat_of_quotient (snd (HOLogic.dest_number a), snd (HOLogic.dest_number b)) |
140 | Const (@{const_name Fields.inverse},_)$t => |
141 | Const (@{const_name Fields.inverse},_)$t => |
141 Rat.inv (Rat.rat_of_int (snd (HOLogic.dest_number t))) |
142 Rat.inv (Rat.rat_of_int (snd (HOLogic.dest_number t))) |
142 | t => Rat.rat_of_int (snd (HOLogic.dest_number t))) |
143 | t => Rat.rat_of_int (snd (HOLogic.dest_number t))) |
143 handle TERM _ => error "ring_dest_const") |
144 handle TERM _ => error "ring_dest_const") |
144 fun mk_const cT x = |
145 fun mk_const cT x = |
145 let val (a, b) = Rat.quotient_of_rat x |
146 let val (a, b) = Rat.quotient_of_rat x |
146 in if b = 1 then Numeral.mk_cnumber cT a |
147 in if b = 1 then Numeral.mk_cnumber cT a |
147 else Thm.apply |
148 else Thm.apply |
163 val ringN = "ring"; |
164 val ringN = "ring"; |
164 val fieldN = "field"; |
165 val fieldN = "field"; |
165 val idomN = "idom"; |
166 val idomN = "idom"; |
166 |
167 |
167 fun declare raw_key |
168 fun declare raw_key |
168 {semiring = raw_semiring, ring = raw_ring, field = raw_field, idom = raw_idom, ideal = raw_ideal} |
169 {semiring = raw_semiring0, ring = raw_ring0, field = raw_field0, idom = raw_idom, ideal = raw_ideal} |
169 phi context = |
170 lthy = |
170 let |
171 let |
171 val ctxt = Context.proof_of context; |
172 val ctxt' = fold Variable.auto_fixes (fst raw_semiring0 @ fst raw_ring0 @ fst raw_field0) lthy; |
172 val key = Morphism.thm phi raw_key; |
173 val prepare_ops = apfst (Variable.export_terms ctxt' lthy #> map (Thm.cterm_of lthy)); |
173 fun morphism_ops_rules (ops, rules) = (map (Morphism.cterm phi) ops, Morphism.fact phi rules); |
174 val raw_semiring = prepare_ops raw_semiring0; |
174 val (sr_ops, sr_rules) = morphism_ops_rules raw_semiring; |
175 val raw_ring = prepare_ops raw_ring0; |
175 val (r_ops, r_rules) = morphism_ops_rules raw_ring; |
176 val raw_field = prepare_ops raw_field0; |
176 val (f_ops, f_rules) = morphism_ops_rules raw_field; |
|
177 val idom = Morphism.fact phi raw_idom; |
|
178 val ideal = Morphism.fact phi raw_ideal; |
|
179 |
|
180 fun check kind name xs n = |
|
181 null xs orelse length xs = n orelse |
|
182 error ("Expected " ^ string_of_int n ^ " " ^ kind ^ " for " ^ name); |
|
183 val check_ops = check "operations"; |
|
184 val check_rules = check "rules"; |
|
185 val _ = |
|
186 check_ops semiringN sr_ops 5 andalso |
|
187 check_rules semiringN sr_rules 36 andalso |
|
188 check_ops ringN r_ops 2 andalso |
|
189 check_rules ringN r_rules 2 andalso |
|
190 check_ops fieldN f_ops 2 andalso |
|
191 check_rules fieldN f_rules 2 andalso |
|
192 check_rules idomN idom 2; |
|
193 |
|
194 val mk_meta = Local_Defs.meta_rewrite_rule ctxt; |
|
195 val sr_rules' = map mk_meta sr_rules; |
|
196 val r_rules' = map mk_meta r_rules; |
|
197 val f_rules' = map mk_meta f_rules; |
|
198 |
|
199 fun rule i = nth sr_rules' (i - 1); |
|
200 |
|
201 val (cx, cy) = Thm.dest_binop (hd sr_ops); |
|
202 val cz = rule 34 |> Thm.rhs_of |> Thm.dest_arg |> Thm.dest_arg; |
|
203 val cn = rule 36 |> Thm.rhs_of |> Thm.dest_arg |> Thm.dest_arg; |
|
204 val ((clx, crx), (cly, cry)) = |
|
205 rule 13 |> Thm.rhs_of |> Thm.dest_binop |> apply2 Thm.dest_binop; |
|
206 val ((ca, cb), (cc, cd)) = |
|
207 rule 20 |> Thm.lhs_of |> Thm.dest_binop |> apply2 Thm.dest_binop; |
|
208 val cm = rule 1 |> Thm.rhs_of |> Thm.dest_arg; |
|
209 val (cp, cq) = rule 26 |> Thm.lhs_of |> Thm.dest_binop |> apply2 Thm.dest_arg; |
|
210 |
|
211 val vars = [ca, cb, cc, cd, cm, cn, cp, cq, cx, cy, cz, clx, crx, cly, cry]; |
|
212 |
|
213 val semiring = (sr_ops, sr_rules'); |
|
214 val ring = (r_ops, r_rules'); |
|
215 val field = (f_ops, f_rules'); |
|
216 val ideal' = map (Thm.symmetric o mk_meta) ideal |
|
217 |
|
218 in |
177 in |
219 context |
178 lthy |> Local_Theory.declaration {syntax = false, pervasive = false} (fn phi => fn context => |
220 |> Data.map (AList.update Thm.eq_thm (key, |
179 let |
221 ({vars = vars, semiring = semiring, ring = ring, field = field, idom = idom, ideal = ideal'}, |
180 val ctxt = Context.proof_of context; |
222 (if null f_ops then semiring_funs else field_funs)))) |
181 val key = Morphism.thm phi raw_key; |
223 end |
182 fun transform_ops_rules (ops, rules) = |
|
183 (map (Morphism.cterm phi) ops, Morphism.fact phi rules); |
|
184 val (sr_ops, sr_rules) = transform_ops_rules raw_semiring; |
|
185 val (r_ops, r_rules) = transform_ops_rules raw_ring; |
|
186 val (f_ops, f_rules) = transform_ops_rules raw_field; |
|
187 val idom = Morphism.fact phi raw_idom; |
|
188 val ideal = Morphism.fact phi raw_ideal; |
|
189 |
|
190 fun check kind name xs n = |
|
191 null xs orelse length xs = n orelse |
|
192 error ("Expected " ^ string_of_int n ^ " " ^ kind ^ " for " ^ name); |
|
193 val check_ops = check "operations"; |
|
194 val check_rules = check "rules"; |
|
195 val _ = |
|
196 check_ops semiringN sr_ops 5 andalso |
|
197 check_rules semiringN sr_rules 36 andalso |
|
198 check_ops ringN r_ops 2 andalso |
|
199 check_rules ringN r_rules 2 andalso |
|
200 check_ops fieldN f_ops 2 andalso |
|
201 check_rules fieldN f_rules 2 andalso |
|
202 check_rules idomN idom 2; |
|
203 |
|
204 val mk_meta = Local_Defs.meta_rewrite_rule ctxt; |
|
205 val sr_rules' = map mk_meta sr_rules; |
|
206 val r_rules' = map mk_meta r_rules; |
|
207 val f_rules' = map mk_meta f_rules; |
|
208 |
|
209 fun rule i = nth sr_rules' (i - 1); |
|
210 |
|
211 val (cx, cy) = Thm.dest_binop (hd sr_ops); |
|
212 val cz = rule 34 |> Thm.rhs_of |> Thm.dest_arg |> Thm.dest_arg; |
|
213 val cn = rule 36 |> Thm.rhs_of |> Thm.dest_arg |> Thm.dest_arg; |
|
214 val ((clx, crx), (cly, cry)) = |
|
215 rule 13 |> Thm.rhs_of |> Thm.dest_binop |> apply2 Thm.dest_binop; |
|
216 val ((ca, cb), (cc, cd)) = |
|
217 rule 20 |> Thm.lhs_of |> Thm.dest_binop |> apply2 Thm.dest_binop; |
|
218 val cm = rule 1 |> Thm.rhs_of |> Thm.dest_arg; |
|
219 val (cp, cq) = rule 26 |> Thm.lhs_of |> Thm.dest_binop |> apply2 Thm.dest_arg; |
|
220 |
|
221 val vars = [ca, cb, cc, cd, cm, cn, cp, cq, cx, cy, cz, clx, crx, cly, cry]; |
|
222 |
|
223 val semiring = (sr_ops, sr_rules'); |
|
224 val ring = (r_ops, r_rules'); |
|
225 val field = (f_ops, f_rules'); |
|
226 val ideal' = map (Thm.symmetric o mk_meta) ideal |
|
227 in |
|
228 context |
|
229 |> Data.map (AList.update Thm.eq_thm (key, |
|
230 ({vars = vars, semiring = semiring, ring = ring, field = field, idom = idom, ideal = ideal'}, |
|
231 (if null f_ops then semiring_funs else field_funs)))) |
|
232 end) |
|
233 end; |
224 |
234 |
225 |
235 |
226 (** auxiliary **) |
236 (** auxiliary **) |
227 |
237 |
228 fun is_comb ct = |
238 fun is_comb ct = |
306 in (neg_mul, sub_add, sub_tm, neg_tm, dest_sub, neg_mul |> concl |> Thm.dest_arg, |
316 in (neg_mul, sub_add, sub_tm, neg_tm, dest_sub, neg_mul |> concl |> Thm.dest_arg, |
307 sub_add |> concl |> Thm.dest_arg |> Thm.dest_arg) |
317 sub_add |> concl |> Thm.dest_arg |> Thm.dest_arg) |
308 end |
318 end |
309 | _ => (TrueI, TrueI, true_tm, true_tm, (fn t => (t,t)), true_tm, true_tm)); |
319 | _ => (TrueI, TrueI, true_tm, true_tm, (fn t => (t,t)), true_tm, true_tm)); |
310 |
320 |
311 val (divide_inverse, divide_tm, inverse_tm) = |
321 val (divide_inverse, divide_tm, inverse_tm) = |
312 (case (f_ops, f_rules) of |
322 (case (f_ops, f_rules) of |
313 ([divide_pat, inverse_pat], [div_inv, _]) => |
323 ([divide_pat, inverse_pat], [div_inv, _]) => |
314 let val div_tm = funpow 2 Thm.dest_fun divide_pat |
324 let val div_tm = funpow 2 Thm.dest_fun divide_pat |
315 val inv_tm = Thm.dest_fun inverse_pat |
325 val inv_tm = Thm.dest_fun inverse_pat |
316 in (div_inv, div_tm, inv_tm) |
326 in (div_inv, div_tm, inv_tm) |
317 end |
327 end |
318 | _ => (TrueI, true_tm, true_tm)); |
328 | _ => (TrueI, true_tm, true_tm)); |
860 fun semiring_normalize_ord_wrapper ctxt ({vars, semiring, ring, field, idom, ideal}, {conv, dest_const, mk_const, is_const}) ord = |
870 fun semiring_normalize_ord_wrapper ctxt ({vars, semiring, ring, field, idom, ideal}, {conv, dest_const, mk_const, is_const}) ord = |
861 #main (semiring_normalizers_ord_wrapper ctxt |
871 #main (semiring_normalizers_ord_wrapper ctxt |
862 ({vars = vars, semiring = semiring, ring = ring, field = field, idom = idom, ideal = ideal}, |
872 ({vars = vars, semiring = semiring, ring = ring, field = field, idom = idom, ideal = ideal}, |
863 {conv = conv, dest_const = dest_const, mk_const = mk_const, is_const = is_const}) ord) ctxt; |
873 {conv = conv, dest_const = dest_const, mk_const = mk_const, is_const = is_const}) ord) ctxt; |
864 |
874 |
865 fun semiring_normalize_wrapper ctxt data = |
875 fun semiring_normalize_wrapper ctxt data = |
866 semiring_normalize_ord_wrapper ctxt data simple_cterm_ord; |
876 semiring_normalize_ord_wrapper ctxt data simple_cterm_ord; |
867 |
877 |
868 fun semiring_normalize_ord_conv ctxt ord tm = |
878 fun semiring_normalize_ord_conv ctxt ord tm = |
869 (case match ctxt tm of |
879 (case match ctxt tm of |
870 NONE => Thm.reflexive tm |
880 NONE => Thm.reflexive tm |
871 | SOME res => semiring_normalize_ord_wrapper ctxt res ord tm); |
881 | SOME res => semiring_normalize_ord_wrapper ctxt res ord tm); |
872 |
882 |
873 fun semiring_normalize_conv ctxt = semiring_normalize_ord_conv ctxt simple_cterm_ord; |
883 fun semiring_normalize_conv ctxt = semiring_normalize_ord_conv ctxt simple_cterm_ord; |
874 |
884 |
875 end; |
885 end; |