Skip to content

Commit 2cb7f4e

Browse files
committed
new quotient theory with explicit canonical map
1 parent 50ae51d commit 2cb7f4e

4 files changed

Lines changed: 120 additions & 135 deletions

File tree

theories/algebra/DynMatrix.eca

Lines changed: 25 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -42,39 +42,17 @@ type prevector = (int -> R) * int.
4242
op vclamp (pv: prevector): prevector =
4343
((fun i => if 0 <= i < pv.`2 then pv.`1 i else zeror), max 0 pv.`2).
4444

45-
lemma vclamp_idemp pv: vclamp (vclamp pv) = vclamp pv.
46-
proof. rewrite /vclamp /#. qed.
47-
48-
op eqv (pv1 pv2: prevector) =
49-
vclamp pv1 = vclamp pv2.
50-
51-
lemma eqv_vclamp pv: eqv pv (vclamp pv).
52-
proof. by rewrite /eqv vclamp_idemp. qed.
53-
54-
clone import Quotient.EquivQuotient as QuotientVec with
55-
type T <- prevector,
56-
op eqv <- eqv
57-
rename [type] "qT" as "vector"
58-
proof * by smt().
59-
60-
type vector = QuotientVec.vector.
61-
62-
op tofunv v = vclamp (repr v).
63-
64-
op offunv pv = pi (vclamp pv).
65-
66-
lemma tofunvK: cancel tofunv offunv.
67-
proof.
68-
rewrite /tofunv /offunv /cancel => v; rewrite vclamp_idemp.
69-
by rewrite -{2}[v]reprK -eqv_pi /eqv vclamp_idemp.
70-
qed.
71-
72-
lemma offunvK pv: tofunv (offunv pv) = vclamp pv.
73-
proof. by rewrite /tofunv /offunv eqv_repr vclamp_idemp. qed.
74-
75-
lemma vectorW (P : vector -> bool):
76-
(forall pv, P (offunv pv)) => forall v, P v.
77-
proof. by move=> P_pv v; rewrite -tofunvK; apply: P_pv. qed.
45+
clone include Quotient.CanonQuotient with
46+
type T <- prevector,
47+
op canon <- vclamp
48+
rename "canon" as "vclamp"
49+
rename "repr" as "tofunv"
50+
rename "pi" as "offunv"
51+
rename "qT" as "vector"
52+
rename "quot" as "vector"
53+
proof * by smt().
54+
55+
hint simplify vclampK, offunvK.
7856

7957
(* Dimension of the vector *)
8058
op size v = (tofunv v).`2.
@@ -86,7 +64,7 @@ lemma max0size v: max 0 (size v) = size v by smt().
8664
hint simplify max0size.
8765

8866
lemma offunv_max f n: offunv (f, max 0 n) = offunv (f, n).
89-
proof. rewrite /offunv -eqv_pi /eqv /vclamp /#. qed.
67+
proof. by rewrite /offunv /vclamp /#. qed.
9068

9169
lemma size_offunv f n: size (offunv (f, n)) = max 0 n.
9270
proof. by rewrite /size offunvK /#. qed.
@@ -100,7 +78,7 @@ abbrev "_.[_]" (v: vector) (i : int) = get v i.
10078

10179
lemma get_offunv f n (i : int) : 0 <= i < n =>
10280
(offunv (f, n)).[i] = f i.
103-
proof. by rewrite /get /= offunvK /vclamp /= => ->. qed.
81+
proof. by rewrite /get /= /vclamp /= => ->. qed.
10482

10583
lemma getv0E v i: !(0 <= i < size v) => v.[i] = zeror by smt().
10684

@@ -665,40 +643,17 @@ op mclamp (pm: prematrix): prematrix =
665643
((fun i j => if 0 <= i < pm.`2 /\ 0 <= j < pm.`3 then pm.`1 i j else zeror),
666644
max 0 pm.`2, max 0 pm.`3).
667645

668-
lemma mclamp_idemp pm: mclamp (mclamp pm) = mclamp pm.
669-
proof. by rewrite /mclamp /#. qed.
670-
671-
hint simplify mclamp_idemp.
672-
673-
op eqv (pm1 pm2: prematrix) = mclamp pm1 = mclamp pm2.
674-
675-
clone import Quotient.EquivQuotient as QuotientMat with
676-
type T <- prematrix,
677-
op eqv <- eqv
678-
rename [type] "qT" as "matrix"
679-
proof * by smt().
680-
681-
type matrix = QuotientMat.matrix.
682-
683-
op tofunm m = mclamp (repr m).
684-
685-
op offunm pm = pi (mclamp pm).
686-
687-
lemma tofunmK : cancel tofunm offunm.
688-
proof.
689-
rewrite /tofunm /offunm /cancel => m /=.
690-
have ->: pi (mclamp (repr m)) = pi (repr m) by rewrite -eqv_pi /eqv.
691-
apply reprK.
692-
qed.
693-
694-
lemma offunmK pm: tofunm (offunm pm) = mclamp pm.
695-
proof. by rewrite /tofunm /offunm eqv_repr. qed.
696-
697-
hint simplify offunmK.
646+
clone include Quotient.CanonQuotient with
647+
type T <- prematrix,
648+
op canon <- mclamp
649+
rename "canon" as "mclamp"
650+
rename "repr" as "tofunm"
651+
rename "pi" as "offunm"
652+
rename "qT" as "matrix"
653+
rename "quot" as "matrix"
654+
proof * by smt().
698655

699-
lemma matrixW (P : matrix -> bool) : (forall pm, P (offunm pm)) =>
700-
forall m, P m.
701-
proof. by move=> P_pm m; rewrite -tofunmK; exact: P_pm. qed.
656+
hint simplify mclampK, offunmK.
702657

703658
(* Number of rows and columns of matrices *)
704659
op rows m = (tofunm m).`2.
@@ -873,7 +828,7 @@ lemma cols_addm (m1 m2: matrix): cols (m1 + m2) = max (cols m1) (cols m2).
873828
proof. rewrite /(+) cols_offunm /#. qed.
874829

875830
lemma size_addm (m1 m2: matrix): size m1 = size m2 => size (m1 + m2) = size m1.
876-
proof. move => size_eq; rewrite rows_addm cols_addm /#. qed.
831+
proof. move => [rows_eq cols_eq]; rewrite rows_addm cols_addm /#. qed.
877832

878833
lemma get_addm (m1 m2 : matrix) i j: (m1 + m2).[i, j] = m1.[i, j] + m2.[i, j].
879834
proof.
@@ -1756,7 +1711,7 @@ qed.
17561711
lemma scalarNm (m: matrix) (s: t): (- s) *** m = - (s *** m).
17571712
proof.
17581713
rewrite eq_matrixP.
1759-
split => [| i j bound]; 1: rewrite !size_scalarm /=; 1: smt(size_scalarm).
1714+
split => [| i j bound]; 1: rewrite !size_scalarm /= rows_scalarm cols_scalarm //.
17601715
by rewrite /= !get_scalarm /= mulrN.
17611716
qed.
17621717

theories/algebra/Matrix.eca

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(* -------------------------------------------------------------------- *)
22
require import AllCore List Distr Perms.
33
require (*--*) Subtype Monoid Ring Subtype Bigalg StdOrder StdBigop.
4+
require (*--*) Quotient.
45

56
import StdOrder.IntOrder StdBigop.Bigreal.
67

@@ -20,21 +21,28 @@ op size : { int | 0 <= size } as ge0_size.
2021
hint exact : ge0_size.
2122

2223
(* -------------------------------------------------------------------- *)
23-
type vector.
24-
2524
theory Vector.
26-
op tofunv : vector -> (int -> R).
27-
op offunv : (int -> R) -> vector.
2825

2926
op prevector (f : int -> R) =
3027
forall i, !(0 <= i < size) => f i = zeror.
3128

3229
op vclamp (v : int -> R) : int -> R =
3330
fun i => if 0 <= i < size then v i else zeror.
3431

35-
axiom tofunv_prevector (v : vector) : prevector (tofunv v).
36-
axiom tofunvK : cancel tofunv offunv.
37-
axiom offunvK : forall v, tofunv (offunv v) = vclamp v.
32+
clone include Quotient.CanonQuotient with
33+
type T <- int -> R,
34+
op canon <- vclamp
35+
rename "canon" as "vclamp"
36+
rename "repr" as "tofunv"
37+
rename "pi" as "offunv"
38+
rename "qT" as "vector"
39+
proof * by smt().
40+
41+
lemma tofunv_prevector (v : vector) : prevector (tofunv v).
42+
proof.
43+
rewrite /prevector /= => i i_bd.
44+
by rewrite -isvclamp_tofunv /vclamp i_bd.
45+
qed.
3846

3947
op "_.[_]" (v : vector) (i : int) = tofunv v i.
4048

@@ -141,7 +149,8 @@ abbrev ( ** ) = scalev.
141149

142150
lemma scalevE a v i : (a ** v).[i] = a * v.[i].
143151
proof.
144-
case: (0 <= i < size) => ?; first smt(offunvK tofunvK).
152+
case: (0 <= i < size) => ?.
153+
- by rewrite offunvE.
145154
by rewrite !getv_out // mulr0.
146155
qed.
147156

@@ -172,10 +181,6 @@ export Vector.
172181

173182
(* -------------------------------------------------------------------- *)
174183
theory Matrix.
175-
type matrix.
176-
177-
op tofunm : matrix -> (int -> int -> R).
178-
op offunm : (int -> int -> R) -> matrix.
179184

180185
abbrev mrange (i j : int) =
181186
0 <= i < size /\ 0 <= j < size.
@@ -195,9 +200,20 @@ op prematrix (f : int -> int -> R) =
195200
op mclamp (m : int -> int -> R) : int -> int -> R =
196201
fun i j : int => if mrange i j then m i j else zeror.
197202

198-
axiom tofunm_prematrix (m : matrix) : prematrix (tofunm m).
199-
axiom tofunmK : cancel tofunm offunm.
200-
axiom offunmK : forall m, tofunm (offunm m) = mclamp m.
203+
clone include Quotient.CanonQuotient with
204+
type T <- int -> int -> R,
205+
op canon <- mclamp
206+
rename "canon" as "mclamp"
207+
rename "repr" as "tofunm"
208+
rename "pi" as "offunm"
209+
rename "qT" as "matrix"
210+
proof * by smt().
211+
212+
lemma tofunm_prematrix (m : matrix) : prematrix (tofunm m).
213+
proof.
214+
rewrite /prematrix /= => i j ij_bd.
215+
by rewrite -ismclamp_tofunm /mclamp ij_bd.
216+
qed.
201217

202218
op "_.[_]" (m : matrix) (ij : int * int) = tofunm m ij.`1 ij.`2.
203219

theories/algebra/PolyReduce.ec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ hint exact : idI.
5858
clone include RingQuotientDflInv with
5959
op p <- I
6060
proof IdealAxioms.*
61-
rename "qT" as "polyXnD1".
61+
rename "qT" as "polyXnD1"
62+
rename "piK" as "piK'".
6263

6364
realize IdealAxioms.ideal_p by apply/idI.
6465

theories/structure/Quotient.ec

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,52 @@ proof. by move=> Py x; rewrite -(reprK x); apply/Py; rewrite reprK. qed.
2929

3030
end CoreQuotient.
3131

32+
(* -------------------------------------------------------------------- *)
33+
(* This theory defines the effective quotient using an idempotent map, *)
34+
(* canon. It builds on the previous theory by using for [qT] the *)
35+
(* elements that are stable under canon. *)
36+
(* -------------------------------------------------------------------- *)
37+
38+
abstract theory CanonQuotient.
39+
40+
type T.
41+
42+
op canon : T -> T.
43+
44+
axiom canonK (x : T): canon (canon x) = canon x.
45+
46+
op iscanon x = canon x = x.
47+
48+
lemma iscanon_canon x : iscanon (canon x).
49+
proof. by rewrite /iscanon canonK. qed.
50+
51+
subtype qT as QSub = {x : T | iscanon x}.
52+
realize inhabited by exists (canon witness); apply canonK.
53+
54+
import QSub.
55+
56+
(* NOTE: The `canon` in `repr` might look like it does nothing, *)
57+
(* but it can make `iscanon_repr` trivial when `iscanon_canon` is *)
58+
clone include CoreQuotient with
59+
type T <- T,
60+
type qT <- qT,
61+
op pi = fun x => QSub.insubd (canon x),
62+
op repr = fun x => canon (QSub.val x)
63+
64+
proof *.
65+
realize reprK by move => q; rewrite /pi /repr canonK valP valKd.
66+
67+
lemma iscanon_repr v : iscanon (repr v) by rewrite iscanon_canon.
68+
69+
lemma piK x : repr (pi x) = canon x.
70+
proof. by rewrite /repr insubdK // iscanon_canon. qed.
71+
72+
end CanonQuotient.
73+
3274
(* -------------------------------------------------------------------- *)
3375
(* This theory defines the effective quotient by an equivalence *)
34-
(* relation. It is build on the former theory, using for [qT] the *)
35-
(* elements of [T] that are stable by repr \o pi. *)
76+
(* relation. It is build on the former theory, using for canon the *)
77+
(* choice map selecting a member of the equivalence class. *)
3678
(* -------------------------------------------------------------------- *)
3779
abstract theory EquivQuotient.
3880

@@ -54,68 +96,39 @@ proof. by exists x; rewrite eqv_refl. qed.
5496
op canon (x : T) = choiceb (eqv x) x.
5597

5698
lemma eqv_canon (x : T) : eqv x (canon x).
57-
proof.
58-
rewrite /canon; apply: (@choicebP (eqv x) x).
59-
by exists x; apply: eqv_refl.
60-
qed.
99+
proof. apply (@choicebP (eqv x) x); by exists x; apply eqv_refl. qed.
61100

62101
lemma eqv_canon_eq (x y : T): eqv x y => canon x = canon y.
63102
proof.
64-
move=> eqv_xy; rewrite /canon (@eq_choice (eqv x) (eqv y)).
65-
- move=> z; split => [eqv_xz|eqv_yz].
66-
- by apply/(eqv_trans x) => //; rewrite eqv_sym.
67-
- by apply/(eqv_trans _ eqv_xy eqv_yz).
68-
by apply: choice_dfl_irrelevant; exists y; apply: eqv_refl.
103+
move=> eqv_xy; rewrite /canon (@eq_choice (eqv x) (eqv y)) => [z|].
104+
- split => [eqv_xz|eqv_yz].
105+
+ by apply (eqv_trans x) => //; rewrite eqv_sym.
106+
+ by apply (eqv_trans _ eqv_xy eqv_yz).
107+
by apply choice_dfl_irrelevant; exists y; apply eqv_refl.
69108
qed.
70109

71-
lemma canonK x : canon (canon x) = canon x.
72-
proof. by rewrite &(eqv_canon_eq) eqv_sym eqv_canon. qed.
73-
74-
op iscanon x = canon x = x.
75-
76-
lemma canon_iscanon x : iscanon x => canon x = x.
77-
proof. by move=> @/iscanon /eq_sym ->; apply: canonK. qed.
110+
clone include CanonQuotient with
111+
type T <- T,
112+
op canon <- canon
113+
proof *.
114+
realize canonK by move => x; rewrite &(eqv_canon_eq) eqv_sym eqv_canon.
78115

79-
lemma iscanon_canon x : iscanon (canon x).
80-
proof. by rewrite /iscanon canonK. qed.
116+
import QSub.
81117

82-
lemma eqvP x y : (eqv x y) <=> (canon x = canon y).
118+
lemma eqvP x y : eqv x y <=> canon x = canon y.
83119
proof.
84120
split=> [/eqv_canon_eq //|eq].
85121
rewrite &(eqv_trans (canon y)) -1:eqv_sym -1:eqv_canon.
86122
apply/(eqv_trans (canon x)); first by apply/eqv_canon.
87123
by rewrite eq &(eqv_refl).
88124
qed.
89125

90-
subtype qT as QSub = { x : T | iscanon x }.
91-
92-
realize inhabited.
93-
proof. smt(canonK). qed.
94-
95-
import QSub.
96-
97-
clone include CoreQuotient with
98-
type T <- T,
99-
type qT <- qT,
100-
op pi = fun x => QSub.insubd (canon x),
101-
op repr = fun x => QSub.val x
102-
103-
proof *.
104-
105-
106-
realize reprK. proof.
107-
by move=> q; rewrite /pi /repr /insubd canon_iscanon 1:valP valK.
108-
qed.
109-
110-
lemma eqv_pi : forall x y , eqv x y <=> pi x = pi y.
126+
lemma eqv_pi x y : eqv x y <=> pi x = pi y.
111127
proof.
112-
move=> x y @/pi; split=> [eq_xy|]; first by congr; apply: eqv_canon_eq.
113-
by move/(congr1 val); rewrite !val_insubd !iscanon_canon /= => /eqvP.
128+
rewrite eqvP /pi; split => [->//|].
129+
by move => /(congr1 val); rewrite !val_insubd !iscanon_canon.
114130
qed.
115131

116-
lemma eqv_repr : forall x, eqv (repr (pi x)) x.
117-
proof.
118-
move=> x @/pi @/repr; rewrite val_insubd.
119-
by rewrite iscanon_canon /= eqv_sym &(eqv_canon).
120-
qed.
132+
lemma eqv_repr x : eqv (repr (pi x)) x.
133+
proof. rewrite /repr val_insubd iscanon_canon eqv_sym /= canonK eqv_canon. qed.
121134
end EquivQuotient.

0 commit comments

Comments
 (0)