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
Require Import Ring_tac BinList Ring_polynom InitialRing.
10
Require Export Field_theory.
13
Ltac mkFieldexpr C Cst CstPow radd rmul rsub ropp rdiv rinv rpow t fv :=
16
| InitialRing.NotConstant =>
20
let e2 := mkP t2 in constr:(FEadd e1 e2)
23
let e2 := mkP t2 in constr:(FEmul e1 e2)
26
let e2 := mkP t2 in constr:(FEsub e1 e2)
28
let e1 := mkP t1 in constr:(FEopp e1)
31
let e2 := mkP t2 in constr:(FEdiv e1 e2)
33
let e1 := mkP t1 in constr:(FEinv e1)
36
| InitialRing.NotConstant =>
37
let p := Find_at t fv in constr:(@FEX C p)
38
| ?c => let e1 := mkP t1 in constr:(FEpow e1 c)
42
let p := Find_at t fv in constr:(@FEX C p)
44
| ?c => constr:(FEc c)
48
Ltac FFV Cst CstPow add mul sub opp div inv pow t fv :=
51
| InitialRing.NotConstant =>
53
| (add ?t1 ?t2) => TFV t2 ltac:(TFV t1 fv)
54
| (mul ?t1 ?t2) => TFV t2 ltac:(TFV t1 fv)
55
| (sub ?t1 ?t2) => TFV t2 ltac:(TFV t1 fv)
56
| (opp ?t1) => TFV t1 fv
57
| (div ?t1 ?t2) => TFV t2 ltac:(TFV t1 fv)
58
| (inv ?t1) => TFV t1 fv
61
| InitialRing.NotConstant => AddFvTail t fv
70
Ltac ParseFieldComponents lemma req :=
71
match type of lemma with
73
(* PCond _ _ _ _ _ _ _ _ _ _ _ -> *)
74
req (@FEeval ?R ?rO ?radd ?rmul ?rsub ?ropp ?rdiv ?rinv
75
?C ?phi ?Cpow ?Cp_phi ?rpow _ _) _ ] =>
76
(fun f => f radd rmul rsub ropp rdiv rinv rpow C)
77
| _ => fail 1 "field anomaly: bad correctness lemma (parse)"
80
(* simplifying the non-zero condition... *)
82
Ltac fold_field_cond req :=
83
let rec fold_concl t :=
86
let fx := fold_concl x in let fy := fold_concl y in constr:(fx/\fy)
87
| req ?x ?y -> False => constr:(~ req x y)
91
|- ?t => let ft := fold_concl t in change ft
94
Ltac simpl_PCond req :=
95
protect_fv "field_cond";
99
Ltac simpl_PCond_BEURK req :=
100
protect_fv "field_cond";
103
(* Rewriting (field_simplify) *)
104
Ltac Field_norm_gen f Cst_tac Pow_tac lemma Cond_lemma req n lH rl :=
105
let Main radd rmul rsub ropp rdiv rinv rpow C :=
106
let mkFV := FV Cst_tac Pow_tac radd rmul rsub ropp rpow in
107
let mkPol := mkPolexpr C Cst_tac Pow_tac radd rmul rsub ropp rpow in
108
let mkFFV := FFV Cst_tac Pow_tac radd rmul rsub ropp rdiv rinv rpow in
110
mkFieldexpr C Cst_tac Pow_tac radd rmul rsub ropp rdiv rinv rpow in
111
let fv := FV_hypo_tac mkFV req lH in
112
let simpl_field H := (protect_fv "field" in H;f H) in
113
let lemma_tac fv RW_tac :=
114
let rr_lemma := fresh "f_rw_lemma" in
115
let lpe := mkHyp_tac C req ltac:(fun t => mkPol t fv) lH in
116
let vlpe := fresh "list_hyp" in
117
let vlmp := fresh "list_hyp_norm" in
118
let vlmp_eq := fresh "list_hyp_norm_eq" in
119
let prh := proofHyp_tac lH in
121
match type of lemma with
122
| context [mk_monpol_list ?cO ?cI ?cadd ?cmul ?csub ?copp ?cdiv ?ceqb _] =>
123
compute_assertion vlmp_eq vlmp
124
(mk_monpol_list cO cI cadd cmul csub copp cdiv ceqb vlpe);
125
(assert (rr_lemma := lemma n vlpe fv prh vlmp vlmp_eq)
126
|| fail 1 "type error when build the rewriting lemma");
128
try clear rr_lemma vlmp_eq vlmp vlpe
129
| _ => fail 1 "field_simplify anomaly: bad correctness lemma"
131
ReflexiveRewriteTactic mkFFV mkFE simpl_field lemma_tac fv rl;
132
try (apply Cond_lemma; simpl_PCond req) in
133
ParseFieldComponents lemma req Main.
135
Ltac Field_simplify_gen f :=
136
fun req cst_tac pow_tac _ _ field_simplify_ok _ cond_ok pre post lH rl =>
138
Field_norm_gen f cst_tac pow_tac field_simplify_ok cond_ok req
139
ring_subst_niter lH rl;
142
Ltac Field_simplify := Field_simplify_gen ltac:(fun H => rewrite H).
144
Tactic Notation (at level 0) "field_simplify" constr_list(rl) :=
146
field_lookup Field_simplify [] rl G.
148
Tactic Notation (at level 0)
149
"field_simplify" "[" constr_list(lH) "]" constr_list(rl) :=
151
field_lookup Field_simplify [lH] rl G.
153
Tactic Notation "field_simplify" constr_list(rl) "in" hyp(H):=
155
let t := type of H in
156
let g := fresh "goal" in
158
generalize H;clear H;
159
field_lookup Field_simplify [] rl t;
163
Tactic Notation "field_simplify"
164
"["constr_list(lH) "]" constr_list(rl) "in" hyp(H):=
166
let t := type of H in
167
let g := fresh "goal" in
169
generalize H;clear H;
170
field_lookup Field_simplify [lH] rl t;
175
Ltac Field_simplify_in hyp:=
176
Field_simplify_gen ltac:(fun H => rewrite H in hyp).
178
Tactic Notation (at level 0)
179
"field_simplify" constr_list(rl) "in" hyp(h) :=
180
let t := type of h in
181
field_lookup (Field_simplify_in h) [] rl t.
183
Tactic Notation (at level 0)
184
"field_simplify" "[" constr_list(lH) "]" constr_list(rl) "in" hyp(h) :=
185
let t := type of h in
186
field_lookup (Field_simplify_in h) [lH] rl t.
189
(** Generic tactic for solving equations *)
191
Ltac Field_Scheme Simpl_tac Cst_tac Pow_tac lemma Cond_lemma req n lH :=
192
let Main radd rmul rsub ropp rdiv rinv rpow C :=
193
let mkFV := FV Cst_tac Pow_tac radd rmul rsub ropp rpow in
194
let mkPol := mkPolexpr C Cst_tac Pow_tac radd rmul rsub ropp rpow in
195
let mkFFV := FFV Cst_tac Pow_tac radd rmul rsub ropp rdiv rinv rpow in
197
mkFieldexpr C Cst_tac Pow_tac radd rmul rsub ropp rdiv rinv rpow in
198
let rec ParseExpr ilemma :=
199
match type of ilemma with
200
forall nfe, ?fe = nfe -> _ =>
202
let x := fresh "fld_expr" in
203
let H := fresh "norm_fld_expr" in
204
compute_assertion H x fe;
205
ParseExpr (ilemma x H) t;
207
| _ => (fun t => t ilemma)
210
let fv := FV_hypo_tac mkFV req lH in
211
let fv := mkFFV t1 fv in
212
let fv := mkFFV t2 fv in
213
let lpe := mkHyp_tac C req ltac:(fun t => mkPol t fv) lH in
214
let prh := proofHyp_tac lH in
215
let vlpe := fresh "list_hyp" in
216
let fe1 := mkFE t1 fv in
217
let fe2 := mkFE t2 fv in
219
let nlemma := fresh "field_lemma" in
220
(assert (nlemma := lemma n fv vlpe fe1 fe2 prh)
221
|| fail "field anomaly:failed to build lemma");
225
|| fail "field anomaly: failed in applying lemma";
226
[ Simpl_tac | apply Cond_lemma; simpl_PCond req]);
228
OnEquation req Main_eq in
229
ParseFieldComponents lemma req Main.
231
(* solve completely a field equation, leaving non-zero conditions to be
235
let Simpl := vm_compute; reflexivity || fail "not a valid field equation" in
236
fun req cst_tac pow_tac field_ok _ _ _ cond_ok pre post lH rl =>
238
Field_Scheme Simpl cst_tac pow_tac field_ok cond_ok req
239
Ring_tac.ring_subst_niter lH;
243
Tactic Notation (at level 0) "field" :=
245
field_lookup FIELD [] G.
247
Tactic Notation (at level 0) "field" "[" constr_list(lH) "]" :=
249
field_lookup FIELD [lH] G.
251
(* transforms a field equation to an equivalent (simplified) ring equation,
252
and leaves non-zero conditions to be proved (field_simplify_eq) *)
254
let Simpl := (protect_fv "field") in
255
fun req cst_tac pow_tac _ field_simplify_eq_ok _ _ cond_ok pre post lH rl =>
257
Field_Scheme Simpl cst_tac pow_tac field_simplify_eq_ok cond_ok
258
req Ring_tac.ring_subst_niter lH;
261
Tactic Notation (at level 0) "field_simplify_eq" :=
263
field_lookup FIELD_SIMPL [] G.
265
Tactic Notation (at level 0) "field_simplify_eq" "[" constr_list(lH) "]" :=
267
field_lookup FIELD_SIMPL [lH] G.
269
(* Same as FIELD_SIMPL but in hypothesis *)
271
Ltac Field_simplify_eq Cst_tac Pow_tac lemma Cond_lemma req n lH :=
272
let Main radd rmul rsub ropp rdiv rinv rpow C :=
273
let hyp := fresh "hyp" in
275
match type of hyp with
277
let mkFV := FV Cst_tac Pow_tac radd rmul rsub ropp rpow in
278
let mkPol := mkPolexpr C Cst_tac Pow_tac radd rmul rsub ropp rpow in
279
let mkFFV := FFV Cst_tac Pow_tac radd rmul rsub ropp rdiv rinv rpow in
281
mkFieldexpr C Cst_tac Pow_tac radd rmul rsub ropp rdiv rinv rpow in
282
let rec ParseExpr ilemma :=
283
match type of ilemma with
284
| forall nfe, ?fe = nfe -> _ =>
286
let x := fresh "fld_expr" in
287
let H := fresh "norm_fld_expr" in
288
compute_assertion H x fe;
289
ParseExpr (ilemma x H) t;
291
| _ => (fun t => t ilemma)
293
let fv := FV_hypo_tac mkFV req lH in
294
let fv := mkFFV t1 fv in
295
let fv := mkFFV t2 fv in
296
let lpe := mkHyp_tac C req ltac:(fun t => mkPol t fv) lH in
297
let prh := proofHyp_tac lH in
298
let fe1 := mkFE t1 fv in
299
let fe2 := mkFE t2 fv in
300
let vlpe := fresh "vlpe" in
301
ParseExpr (lemma n fv lpe fe1 fe2 prh)
303
match type of ilemma with
304
| req _ _ -> _ -> ?EQ =>
305
let tmp := fresh "tmp" in
308
[ exact hyp | apply Cond_lemma; simpl_PCond_BEURK req]
309
| protect_fv "field" in tmp;
310
generalize tmp;clear tmp ];
314
ParseFieldComponents lemma req Main.
316
Ltac FIELD_SIMPL_EQ :=
317
fun req cst_tac pow_tac _ _ _ lemma cond_ok pre post lH rl =>
319
Field_simplify_eq cst_tac pow_tac lemma cond_ok req
320
Ring_tac.ring_subst_niter lH;
323
Tactic Notation (at level 0) "field_simplify_eq" "in" hyp(H) :=
324
let t := type of H in
326
field_lookup FIELD_SIMPL_EQ [] t;
331
Tactic Notation (at level 0)
332
"field_simplify_eq" "[" constr_list(lH) "]" "in" hyp(H) :=
333
let t := type of H in
335
field_lookup FIELD_SIMPL_EQ [lH] t;
339
(* Adding a new field *)
341
Ltac ring_of_field f :=
343
| almost_field_theory _ _ _ _ _ _ _ _ _ => constr:(AF_AR f)
344
| field_theory _ _ _ _ _ _ _ _ _ => constr:(F_R f)
345
| semi_field_theory _ _ _ _ _ _ _ => constr:(SF_SR f)
348
Ltac coerce_to_almost_field set ext f :=
350
| almost_field_theory _ _ _ _ _ _ _ _ _ => f
351
| field_theory _ _ _ _ _ _ _ _ _ => constr:(F2AF set ext f)
352
| semi_field_theory _ _ _ _ _ _ _ => constr:(SF2AF set f)
355
Ltac field_elements set ext fspec pspec sspec dspec rk :=
356
let afth := coerce_to_almost_field set ext fspec in
357
let rspec := ring_of_field fspec in
358
ring_elements set ext rspec pspec sspec dspec rk
359
ltac:(fun arth ext_r morph p_spec s_spec d_spec f => f afth ext_r morph p_spec s_spec d_spec).
361
Ltac field_lemmas set ext inv_m fspec pspec sspec dspec rk :=
363
match pspec with None => fun x y => x | _ => fun x y => y end in
364
let simpl_eq_lemma := get_lemma
365
Field_simplify_eq_correct Field_simplify_eq_pow_correct in
366
let simpl_eq_in_lemma := get_lemma
367
Field_simplify_eq_in_correct Field_simplify_eq_pow_in_correct in
368
let rw_lemma := get_lemma
369
Field_rw_correct Field_rw_pow_correct in
370
field_elements set ext fspec pspec sspec dspec rk
371
ltac:(fun afth ext_r morph p_spec s_spec d_spec =>
374
let field_ok1 := constr:(Field_correct set ext_r inv_m afth morph) in
377
let field_ok2 := constr:(field_ok1 _ _ _ pp_spec) in
380
let field_ok3 := constr:(field_ok2 _ ss_spec) in
383
let field_ok := constr:(field_ok3 _ dd_spec) in
384
let mk_lemma lemma :=
385
constr:(lemma _ _ _ _ _ _ _ _ _ _
387
_ _ _ _ _ _ _ _ _ morph
388
_ _ _ pp_spec _ ss_spec _ dd_spec) in
389
let field_simpl_eq_ok := mk_lemma simpl_eq_lemma in
390
let field_simpl_ok := mk_lemma rw_lemma in
391
let field_simpl_eq_in := mk_lemma simpl_eq_in_lemma in
393
constr:(Pcond_simpl_gen set ext_r afth morph pp_spec dd_spec) in
395
constr:(Pcond_simpl_complete set ext_r afth morph pp_spec dd_spec) in
397
f afth ext_r morph field_ok field_simpl_ok field_simpl_eq_ok field_simpl_eq_in
399
| _ => fail 4 "field: bad coefficiant division specification"
401
| _ => fail 3 "field: bad sign specification"
403
| _ => fail 2 "field: bad power specification"
405
| _ => fail 1 "field internal error : field_lemmas, please report"