Skip to content

Commit 67117a9

Browse files
committed
split off and generalize Kronecker Delta in own file
Signed-off-by: Ali Caglayan <alizter@gmail.com>
1 parent 38c8dca commit 67117a9

File tree

2 files changed

+148
-136
lines changed

2 files changed

+148
-136
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
Require Import Basics.Overture Basics.Decidable Spaces.Nat.
2+
Require Import Algebra.Rings.Ring.
3+
Require Import Classes.interfaces.abstract_algebra.
4+
5+
(** ** Kronecker Delta *)
6+
7+
Section AssumeDecidable.
8+
(** Throughout this section, we assume that we have a type [A] with decidable equality. This will be our indexing type and can be thought of as [nat] for reading purposes. *)
9+
10+
Context {A : Type} `{DecidablePaths A}.
11+
12+
(** The Kronecker delta function is a function of elements of [A] that is 1 when the two numbers are equal and 0 otherwise. It is useful for working with finite sums of ring elements. *)
13+
Definition kronecker_delta {R : Ring} (i j : A) : R
14+
:= if dec (i = j) then 1 else 0.
15+
16+
(** Kronecker delta with the same index is 1. *)
17+
Definition kronecker_delta_refl {R : Ring} (i : A)
18+
: kronecker_delta (R:=R) i i = 1.
19+
Proof.
20+
unfold kronecker_delta.
21+
generalize (dec (i = i)).
22+
by rapply decidable_paths_refl.
23+
Defined.
24+
25+
(** Kronecker delta with differing indices is 0. *)
26+
Definition kronecker_delta_neq {R : Ring} {i j : A} (p : i <> j)
27+
: kronecker_delta (R:=R) i j = 0.
28+
Proof.
29+
unfold kronecker_delta.
30+
by decidable_false (dec (i = j)) p.
31+
Defined.
32+
33+
(** Kronecker delta is symmetric in its arguments. *)
34+
Definition kronecker_delta_symm {R : Ring} (i j : A)
35+
: kronecker_delta (R:=R) i j = kronecker_delta j i.
36+
Proof.
37+
unfold kronecker_delta.
38+
destruct (dec (i = j)) as [p|q].
39+
- by decidable_true (dec (j = i)) p^.
40+
- by decidable_false (dec (j = i)) (symmetric_neq q).
41+
Defined.
42+
43+
(** An injective endofunction on [A] preserves the Kronecker delta. *)
44+
Definition kronecker_delta_map_inj {R : Ring} (i j : A) (f : A -> A)
45+
`{!IsInjective f}
46+
: kronecker_delta (R:=R) (f i) (f j) = kronecker_delta i j.
47+
Proof.
48+
unfold kronecker_delta.
49+
destruct (dec (i = j)) as [p|p].
50+
- by decidable_true (dec (f i = f j)) (ap f p).
51+
- destruct (dec (f i = f j)) as [q|q].
52+
+ apply (injective f) in q.
53+
contradiction.
54+
+ reflexivity.
55+
Defined.
56+
57+
(** Kronecker delta commutes with any ring element. *)
58+
Definition kronecker_delta_comm {R : Ring} (i j : A) (r : R)
59+
: r * kronecker_delta i j = kronecker_delta i j * r.
60+
Proof.
61+
unfold kronecker_delta.
62+
destruct (dec (i = j)).
63+
- exact (rng_mult_one_r _ @ (rng_mult_one_l _)^).
64+
- exact (rng_mult_zero_r _ @ (rng_mult_zero_l _)^).
65+
Defined.
66+
67+
End AssumeDecidable.
68+
69+
(** The following lemmas are specialised to when the indexing type is [nat]. *)
70+
71+
(** Kronecker delta where the first index is strictly less than the second is 0. *)
72+
Definition kronecker_delta_lt {R : Ring} {i j : nat} (p : (i < j)%nat)
73+
: kronecker_delta (R:=R) i j = 0.
74+
Proof.
75+
apply kronecker_delta_neq.
76+
intros q; destruct q.
77+
by apply not_lt_n_n in p.
78+
Defined.
79+
80+
(** Kronecker delta where the first index is strictly greater than the second is 0. *)
81+
Definition kronecker_delta_gt {R : Ring} {i j : nat} (p : (j < i)%nat)
82+
: kronecker_delta (R:=R) i j = 0.
83+
Proof.
84+
apply kronecker_delta_neq.
85+
intros q; destruct q.
86+
by apply not_lt_n_n in p.
87+
Defined.
88+
89+
(** Kronecker delta can be used to extract a single term from a finite sum. *)
90+
Definition rng_sum_kronecker_delta_l {R : Ring} (n i : nat) (Hi : (i < n)%nat)
91+
(f : forall k, (k < n)%nat -> R)
92+
: rng_sum n (fun j Hj => kronecker_delta i j * f j Hj) = f i Hi.
93+
Proof.
94+
induction n as [|n IHn] in i, Hi, f |- *.
95+
1: destruct (not_leq_Sn_0 _ Hi).
96+
destruct (dec (i = n)) as [p|p].
97+
- destruct p; simpl.
98+
rewrite kronecker_delta_refl.
99+
rewrite rng_mult_one_l.
100+
rewrite <- rng_plus_zero_r.
101+
f_ap; [f_ap; rapply path_ishprop|].
102+
nrapply rng_sum_zero.
103+
intros k Hk.
104+
rewrite (kronecker_delta_gt Hk).
105+
apply rng_mult_zero_l.
106+
- simpl; lhs nrapply ap.
107+
+ nrapply IHn.
108+
apply diseq_implies_lt in p.
109+
destruct p; [assumption|].
110+
contradiction (lt_implies_not_geq Hi).
111+
+ rewrite (kronecker_delta_neq p).
112+
rewrite rng_mult_zero_l.
113+
rewrite rng_plus_zero_l.
114+
f_ap; apply path_ishprop.
115+
Defined.
116+
117+
(** Variant of [rng_sum_kronecker_delta_l] where the indexing is swapped. *)
118+
Definition rng_sum_kronecker_delta_l' {R : Ring} (n i : nat) (Hi : (i < n)%nat)
119+
(f : forall k, (k < n)%nat -> R)
120+
: rng_sum n (fun j Hj => kronecker_delta j i * f j Hj) = f i Hi.
121+
Proof.
122+
lhs nrapply path_rng_sum.
123+
2: nrapply rng_sum_kronecker_delta_l.
124+
intros k Hk.
125+
cbn; f_ap; apply kronecker_delta_symm.
126+
Defined.
127+
128+
(** Variant of [rng_sum_kronecker_delta_l] where the Kronecker delta appears on the right. *)
129+
Definition rng_sum_kronecker_delta_r {R : Ring} (n i : nat) (Hi : (i < n)%nat)
130+
(f : forall k, (k < n)%nat -> R)
131+
: rng_sum n (fun j Hj => f j Hj * kronecker_delta i j) = f i Hi.
132+
Proof.
133+
lhs nrapply path_rng_sum.
134+
2: nrapply rng_sum_kronecker_delta_l.
135+
intros k Hk.
136+
apply kronecker_delta_comm.
137+
Defined.
138+
139+
(** Variant of [rng_sum_kronecker_delta_r] where the indexing is swapped. *)
140+
Definition rng_sum_kronecker_delta_r' {R : Ring} (n i : nat) (Hi : (i < n)%nat)
141+
(f : forall k, (k < n)%nat -> R)
142+
: rng_sum n (fun j Hj => f j Hj * kronecker_delta j i) = f i Hi.
143+
Proof.
144+
lhs nrapply path_rng_sum.
145+
2: nrapply rng_sum_kronecker_delta_l'.
146+
intros k Hk.
147+
apply kronecker_delta_comm.
148+
Defined.

theories/Algebra/Rings/Ring.v

Lines changed: 0 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -561,139 +561,3 @@ Proof.
561561
1: apply rng_mult_zero_l.
562562
lhs nrapply rng_dist_r; simpl; f_ap.
563563
Defined.
564-
565-
(** ** Kronecker Delta *)
566-
567-
(** The Kronecker delta function is a function of two natural numbers that is 1 when the two numbers are equal and 0 otherwise. It is useful for working with finite sums of ring elements. *)
568-
Definition kronecker_delta {R : Ring} (i j : nat) : R
569-
:= if dec (i = j) then 1 else 0.
570-
571-
(** Kronecker delta with the same index is 1. This holds definitionally for a given natural number, but not definitionally for an arbitrary one. *)
572-
Definition kronecker_delta_refl {R : Ring} (i : nat)
573-
: kronecker_delta (R:=R) i i = 1.
574-
Proof.
575-
unfold kronecker_delta.
576-
generalize (dec (i = i)).
577-
by rapply decidable_paths_refl.
578-
Defined.
579-
580-
(** Kronecker delta with different indices is 0. *)
581-
Definition kronecker_delta_neq {R : Ring} {i j : nat} (p : i <> j)
582-
: kronecker_delta (R:=R) i j = 0.
583-
Proof.
584-
unfold kronecker_delta.
585-
by decidable_false (dec (i = j)) p.
586-
Defined.
587-
588-
(** Kronecker delta is symmetric in its arguments. *)
589-
Definition kronecker_delta_symm {R : Ring} (i j : nat)
590-
: kronecker_delta (R:=R) i j = kronecker_delta j i.
591-
Proof.
592-
unfold kronecker_delta.
593-
destruct (dec (i = j)) as [p|q].
594-
- by decidable_true (dec (j = i)) p^.
595-
- by decidable_false (dec (j = i)) (symmetric_neq q).
596-
Defined.
597-
598-
(** Kronecker delta where the first index is strictly less than the second is 0. *)
599-
Definition kronecker_delta_lt {R : Ring} {i j : nat} (p : (i < j)%nat)
600-
: kronecker_delta (R:=R) i j = 0.
601-
Proof.
602-
apply kronecker_delta_neq.
603-
intros q; destruct q.
604-
by apply not_lt_n_n in p.
605-
Defined.
606-
607-
(** Kronecker delta where the first index is strictly greater than the second is 0. *)
608-
Definition kronecker_delta_gt {R : Ring} {i j : nat} (p : (j < i)%nat)
609-
: kronecker_delta (R:=R) i j = 0.
610-
Proof.
611-
apply kronecker_delta_neq.
612-
intros q; destruct q.
613-
by apply not_lt_n_n in p.
614-
Defined.
615-
616-
(** An injective endofunction on nat preserves the Kronecker delta. *)
617-
Definition kronecker_delta_map_inj {R : Ring} (i j : nat) (f : nat -> nat)
618-
`{!IsInjective f}
619-
: kronecker_delta (R:=R) (f i) (f j) = kronecker_delta i j.
620-
Proof.
621-
unfold kronecker_delta.
622-
destruct (dec (i = j)) as [p|p].
623-
- by decidable_true (dec (f i = f j)) (ap f p).
624-
- destruct (dec (f i = f j)) as [q|q].
625-
+ apply (injective f) in q.
626-
contradiction.
627-
+ reflexivity.
628-
Defined.
629-
630-
(** Kronecker delta commutes with any ring element. *)
631-
Definition kronecker_delta_comm {R : Ring} (i j : nat) (r : R)
632-
: r * kronecker_delta i j = kronecker_delta i j * r.
633-
Proof.
634-
unfold kronecker_delta.
635-
destruct (dec (i = j)).
636-
- exact (rng_mult_one_r _ @ (rng_mult_one_l _)^).
637-
- exact (rng_mult_zero_r _ @ (rng_mult_zero_l _)^).
638-
Defined.
639-
640-
(** Kronecker delta can be used to extract a single term from a finite sum. *)
641-
Definition rng_sum_kronecker_delta_l {R : Ring} (n i : nat) (Hi : (i < n)%nat)
642-
(f : forall k, (k < n)%nat -> R)
643-
: rng_sum n (fun j Hj => kronecker_delta i j * f j Hj) = f i Hi.
644-
Proof.
645-
induction n as [|n IHn] in i, Hi, f |- *.
646-
1: destruct (not_leq_Sn_0 _ Hi).
647-
destruct (dec (i = n)) as [p|p].
648-
- destruct p; simpl.
649-
rewrite kronecker_delta_refl.
650-
rewrite rng_mult_one_l.
651-
rewrite <- rng_plus_zero_r.
652-
f_ap; [f_ap; rapply path_ishprop|].
653-
nrapply rng_sum_zero.
654-
intros k Hk.
655-
rewrite (kronecker_delta_gt Hk).
656-
apply rng_mult_zero_l.
657-
- simpl; lhs nrapply ap.
658-
+ nrapply IHn.
659-
apply diseq_implies_lt in p.
660-
destruct p; [assumption|].
661-
contradiction (lt_implies_not_geq Hi).
662-
+ rewrite (kronecker_delta_neq p).
663-
rewrite rng_mult_zero_l.
664-
rewrite rng_plus_zero_l.
665-
f_ap; apply path_ishprop.
666-
Defined.
667-
668-
(** Variant of [rng_sum_kronecker_delta_l] where the indexing is swapped. *)
669-
Definition rng_sum_kronecker_delta_l' {R : Ring} (n i : nat) (Hi : (i < n)%nat)
670-
(f : forall k, (k < n)%nat -> R)
671-
: rng_sum n (fun j Hj => kronecker_delta j i * f j Hj) = f i Hi.
672-
Proof.
673-
lhs nrapply path_rng_sum.
674-
2: nrapply rng_sum_kronecker_delta_l.
675-
intros k Hk.
676-
cbn; f_ap; apply kronecker_delta_symm.
677-
Defined.
678-
679-
(** Variant of [rng_sum_kronecker_delta_l] where the Kronecker delta appears on the right. *)
680-
Definition rng_sum_kronecker_delta_r {R : Ring} (n i : nat) (Hi : (i < n)%nat)
681-
(f : forall k, (k < n)%nat -> R)
682-
: rng_sum n (fun j Hj => f j Hj * kronecker_delta i j) = f i Hi.
683-
Proof.
684-
lhs nrapply path_rng_sum.
685-
2: nrapply rng_sum_kronecker_delta_l.
686-
intros k Hk.
687-
apply kronecker_delta_comm.
688-
Defined.
689-
690-
(** Variant of [rng_sum_kronecker_delta_r] where the indexing is swapped. *)
691-
Definition rng_sum_kronecker_delta_r' {R : Ring} (n i : nat) (Hi : (i < n)%nat)
692-
(f : forall k, (k < n)%nat -> R)
693-
: rng_sum n (fun j Hj => f j Hj * kronecker_delta j i) = f i Hi.
694-
Proof.
695-
lhs nrapply path_rng_sum.
696-
2: nrapply rng_sum_kronecker_delta_l'.
697-
intros k Hk.
698-
apply kronecker_delta_comm.
699-
Defined.

0 commit comments

Comments
 (0)