1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(* $Id: LegacyField_Tactic.v 9319 2006-10-30 12:41:21Z barras $ *)
12
Require Import LegacyRing.
13
Require Export LegacyField_Compl.
14
Require Export LegacyField_Theory.
16
(**** Interpretation A --> ExprA ****)
18
Ltac get_component a s := eval cbv beta iota delta [a] in (a s).
20
Ltac body_of s := eval cbv beta iota delta [s] in s.
22
Ltac mem_assoc var lvar :=
23
match constr:lvar with
26
match constr:(X1 = var) with
27
| (?X1 = ?X1) => constr:true
28
| _ => mem_assoc var X2
33
let rec number_aux lvar cpt :=
34
match constr:lvar with
35
| (@nil ?X1) => constr:(@nil (prod X1 nat))
37
let l2 := number_aux X3 (S cpt) in
38
constr:((X2,cpt) :: l2)
42
Ltac build_varlist FT trm :=
43
let rec seek_var lvar trm :=
44
let AT := get_component A FT
45
with AzeroT := get_component Azero FT
46
with AoneT := get_component Aone FT
47
with AplusT := get_component Aplus FT
48
with AmultT := get_component Amult FT
49
with AoppT := get_component Aopp FT
50
with AinvT := get_component Ainv FT in
55
let l1 := seek_var lvar X1 in
58
let l1 := seek_var lvar X1 in
60
| (AoppT ?X1) => seek_var lvar X1
61
| (AinvT ?X1) => seek_var lvar X1
63
let res := mem_assoc X1 lvar in
66
| false => constr:(X1 :: lvar)
69
let AT := get_component A FT in
70
let lvar := seek_var (@nil AT) trm in
77
match constr:(elt = X1) with
78
| (?X1 = ?X1) => constr:X2
83
Ltac interp_A FT lvar trm :=
84
let AT := get_component A FT
85
with AzeroT := get_component Azero FT
86
with AoneT := get_component Aone FT
87
with AplusT := get_component Aplus FT
88
with AmultT := get_component Amult FT
89
with AoppT := get_component Aopp FT
90
with AinvT := get_component Ainv FT in
92
| AzeroT => constr:EAzero
93
| AoneT => constr:EAone
95
let e1 := interp_A FT lvar X1 with e2 := interp_A FT lvar X2 in
98
let e1 := interp_A FT lvar X1 with e2 := interp_A FT lvar X2 in
101
let e := interp_A FT lvar X1 in
103
| (AinvT ?X1) => let e := interp_A FT lvar X1 in
105
| ?X1 => let idx := assoc X1 lvar in
109
(************************)
111
(************************)
113
(**** Generation of the multiplier ****)
118
| e :: ?X2 => constr:X2
119
| ?X2 :: ?X3 => let nl := remove e X3 in constr:(X2 :: nl)
126
let nl2 := remove X2 l2 in
127
let nl := union X3 nl2 in
131
Ltac raw_give_mult trm :=
132
match constr:trm with
133
| (EAinv ?X1) => constr:(X1 :: nil)
134
| (EAopp ?X1) => raw_give_mult X1
135
| (EAplus ?X1 ?X2) =>
136
let l1 := raw_give_mult X1 with l2 := raw_give_mult X2 in
138
| (EAmult ?X1 ?X2) =>
139
let l1 := raw_give_mult X1 with l2 := raw_give_mult X2 in
140
eval compute in (app l1 l2)
141
| _ => constr:(@nil ExprA)
144
Ltac give_mult trm :=
145
let ltrm := raw_give_mult trm in
146
constr:(mult_of_list ltrm).
148
(**** Associativity ****)
150
Ltac apply_assoc FT lvar trm :=
151
let t := eval compute in (assoc trm) in
152
match constr:(t = trm) with
153
| (?X1 = ?X1) => idtac
155
rewrite <- (assoc_correct FT trm); change (assoc trm) with t in |- *
158
(**** Distribution *****)
160
Ltac apply_distrib FT lvar trm :=
161
let t := eval compute in (distrib trm) in
162
match constr:(t = trm) with
163
| (?X1 = ?X1) => idtac
165
rewrite <- (distrib_correct FT trm);
166
change (distrib trm) with t in |- *
169
(**** Multiplication by the inverse product ****)
171
Ltac grep_mult := match goal with
172
| id:(interp_ExprA _ _ _ <> _) |- _ => id
177
| |- context [(interp_ExprA ?X1 ?X2 _)] =>
179
delta [interp_ExprA assoc_2nd eq_nat_dec mult_of_list X1 X2 A Azero
180
Aone Aplus Amult Aopp Ainv] in |- *
185
| |- (interp_ExprA ?FT ?X2 ?X3 = interp_ExprA ?FT ?X2 ?X4) =>
186
let AzeroT := get_component Azero FT in
187
cut (interp_ExprA FT X2 mul <> AzeroT);
188
[ intro; (let id := grep_mult in apply (mult_eq FT X3 X4 mul X2 id))
190
(let AoneT := get_component Aone ltac:(body_of FT)
191
with AmultT := get_component Amult ltac:(body_of FT) in
194
| |- context [(AmultT _ AoneT)] => rewrite (AmultT_1r FT)
198
Ltac apply_multiply FT lvar trm :=
199
let t := eval compute in (multiply trm) in
200
match constr:(t = trm) with
201
| (?X1 = ?X1) => idtac
203
rewrite <- (multiply_correct FT trm);
204
change (multiply trm) with t in |- *
207
(**** Permutations and simplification ****)
209
Ltac apply_inverse mul FT lvar trm :=
210
let t := eval compute in (inverse_simplif mul trm) in
211
match constr:(t = trm) with
212
| (?X1 = ?X1) => idtac
214
rewrite <- (inverse_correct FT trm mul);
215
[ change (inverse_simplif mul trm) with t in |- * | assumption ]
217
(**** Inverse test ****)
219
Ltac strong_fail tac := first [ tac | fail 2 ].
221
Ltac inverse_test_aux FT trm :=
222
let AplusT := get_component Aplus FT
223
with AmultT := get_component Amult FT
224
with AoppT := get_component Aopp FT
225
with AinvT := get_component Ainv FT in
226
match constr:trm with
227
| (AinvT _) => fail 1
229
strong_fail ltac:(inverse_test_aux FT X1; idtac)
230
| (AplusT ?X1 ?X2) =>
231
strong_fail ltac:(inverse_test_aux FT X1; inverse_test_aux FT X2)
232
| (AmultT ?X1 ?X2) =>
233
strong_fail ltac:(inverse_test_aux FT X1; inverse_test_aux FT X2)
237
Ltac inverse_test FT :=
238
let AplusT := get_component Aplus FT in
240
| |- (?X1 = ?X2) => inverse_test_aux FT (AplusT X1 X2)
243
(**** Field itself ****)
245
Ltac apply_simplif sfun :=
247
| |- (interp_ExprA ?X1 ?X2 ?X3 = interp_ExprA _ _ _) =>
251
| |- (interp_ExprA _ _ _ = interp_ExprA ?X1 ?X2 ?X3) =>
256
match get_component Aminus FT with
257
| Some ?X1 => unfold X1 in |- *
260
match get_component Adiv FT with
261
| Some ?X1 => unfold X1 in |- *
266
let AzeroT := get_component Azero FT
267
with AoneT := get_component Aone FT
268
with AplusT := get_component Aplus FT
269
with AmultT := get_component Amult FT
270
with AoppT := get_component Aopp FT
271
with AinvT := get_component Ainv FT in
272
(cbv beta iota zeta delta -[AzeroT AoneT AplusT AmultT AoppT AinvT] in |- * ||
275
Ltac field_gen_aux FT :=
276
let AplusT := get_component Aplus FT in
279
let lvar := build_varlist FT (AplusT X1 X2) in
280
let trm1 := interp_A FT lvar X1 with trm2 := interp_A FT lvar X2 in
281
let mul := give_mult (EAplus trm1 trm2) in
284
let vm := lvar in interp_ExprA ft vm trm1 = interp_ExprA ft vm trm2);
285
[ compute in |- *; auto
286
| intros ft vm; apply_simplif apply_distrib;
287
apply_simplif apply_assoc; multiply mul;
288
[ apply_simplif apply_multiply;
289
apply_simplif ltac:(apply_inverse mul);
290
(let id := grep_mult in
291
clear id; weak_reduce; clear ft vm; first
292
[ inverse_test FT; legacy ring | field_gen_aux FT ])
297
unfolds FT; (inverse_test FT; legacy ring) || field_gen_aux FT.
299
(*****************************)
300
(* Term Simplification *)
301
(*****************************)
303
(**** Minus and division expansions ****)
305
Ltac init_exp FT trm :=
307
(match get_component Aminus FT with
308
| Some ?X1 => eval cbv beta delta [X1] in trm
311
match get_component Adiv FT with
312
| Some ?X1 => eval cbv beta delta [X1] in e
316
(**** Inverses simplification ****)
318
Ltac simpl_inv trm :=
319
match constr:trm with
320
| (EAplus ?X1 ?X2) =>
321
let e1 := simpl_inv X1 with e2 := simpl_inv X2 in
322
constr:(EAplus e1 e2)
323
| (EAmult ?X1 ?X2) =>
324
let e1 := simpl_inv X1 with e2 := simpl_inv X2 in
325
constr:(EAmult e1 e2)
326
| (EAopp ?X1) => let e := simpl_inv X1 in
328
| (EAinv ?X1) => SimplInvAux X1
331
with SimplInvAux trm :=
332
match constr:trm with
333
| (EAinv ?X1) => simpl_inv X1
334
| (EAmult ?X1 ?X2) =>
335
let e1 := simpl_inv (EAinv X1) with e2 := simpl_inv (EAinv X2) in
336
constr:(EAmult e1 e2)
337
| ?X1 => let e := simpl_inv X1 in
341
(**** Monom simplification ****)
343
Ltac map_tactic fcn lst :=
344
match constr:lst with
347
let r := fcn X2 with t := map_tactic fcn X3 in
351
Ltac build_monom_aux lst trm :=
352
match constr:lst with
353
| nil => eval compute in (assoc trm)
354
| ?X1 :: ?X2 => build_monom_aux X2 (EAmult trm X1)
357
Ltac build_monom lnum lden :=
358
let ildn := map_tactic ltac:(fun e => constr:(EAinv e)) lden in
359
let ltot := eval compute in (app lnum ildn) in
360
let trm := build_monom_aux ltot EAone in
361
match constr:trm with
362
| (EAmult _ ?X1) => constr:X1
366
Ltac simpl_monom_aux lnum lden trm :=
367
match constr:trm with
368
| (EAmult (EAinv ?X1) ?X2) =>
369
let mma := mem_assoc X1 lnum in
370
match constr:mma with
372
let newlnum := remove X1 lnum in
373
simpl_monom_aux newlnum lden X2
374
| false => simpl_monom_aux lnum (X1 :: lden) X2
376
| (EAmult ?X1 ?X2) =>
377
let mma := mem_assoc X1 lden in
378
match constr:mma with
380
let newlden := remove X1 lden in
381
simpl_monom_aux lnum newlden X2
382
| false => simpl_monom_aux (X1 :: lnum) lden X2
385
let mma := mem_assoc X1 lnum in
386
match constr:mma with
388
let newlnum := remove X1 lnum in
389
build_monom newlnum lden
390
| false => build_monom lnum (X1 :: lden)
393
let mma := mem_assoc X1 lden in
394
match constr:mma with
396
let newlden := remove X1 lden in
397
build_monom lnum newlden
398
| false => build_monom (X1 :: lnum) lden
402
Ltac simpl_monom trm := simpl_monom_aux (@nil ExprA) (@nil ExprA) trm.
404
Ltac simpl_all_monomials trm :=
405
match constr:trm with
406
| (EAplus ?X1 ?X2) =>
407
let e1 := simpl_monom X1 with e2 := simpl_all_monomials X2 in
408
constr:(EAplus e1 e2)
409
| ?X1 => simpl_monom X1
412
(**** Associativity and distribution ****)
414
Ltac assoc_distrib trm := eval compute in (assoc (distrib trm)).
416
(**** The tactic Field_Term ****)
418
Ltac eval_weak_reduce trm :=
421
delta [interp_ExprA assoc_2nd eq_nat_dec mult_of_list A Azero Aone Aplus
422
Amult Aopp Ainv] in trm.
424
Ltac field_term FT exp :=
425
let newexp := init_exp FT exp in
426
let lvar := build_varlist FT newexp in
427
let trm := interp_A FT lvar newexp in
428
let tma := eval compute in (assoc trm) in
431
ltac:(assoc_distrib ltac:(simpl_all_monomials ltac:(simpl_inv tma))) in
432
let trep := eval_weak_reduce (interp_ExprA FT lvar tsmp) in
433
(replace exp with trep; [ legacy ring trep | field_gen FT ]).