From mathcomp Require Import all_ssreflect ssralg.
Require Import isomorphism axioms.
Class Zero T := { zero : T }.
(* The nth-order infinitesimals. *)
Definition nilpotent n := {x : R | x ^+ n = 0}.
Definition nilpotent_union := {x : R | exists n, x ^+ n = 0}.
Notation "''D_' n" := (nilpotent (n.+1))
(at level 8, n at level 2, format "''D_' n").
Notation "''D_-1'" := (nilpotent 0)
(at level 8, format "''D_-1'").
Notation "''D_∞'" := nilpotent_union
(at level 8, format "''D_∞'").
Coercion R_of_nilpotent_union (d : nilpotent_union) : R := proj1_sig d.
Coercion union_of_nilpotent {n} : nilpotent n -> 'D_∞.
move=> [x pf].
exists x.
exists n.
exact pf.
Defined.
Fact higher_power_still_zero {x : R} {m n} (leq : m <= n)
: x ^+ m = 0 -> x ^+ n = 0.
Proof.
rewrite -(subnK leq) exprD => ->.
apply: mulr0.
Qed.
Definition widen_nilpotent {m n} (leq : m <= n) : nilpotent m -> nilpotent n :=
fun '(exist x pf) => (exist _ x (higher_power_still_zero leq pf)).
#[refine]
Global Instance D_zero {n} : Zero 'D_n := {
zero := exist _ 0 _
}.
apply: expr0n.
Defined.
Global Instance nilpotent_union_zero : Zero nilpotent_union := {
zero := (zero : 'D_0)
}.
Definition d_minus_void_iso : 'D_-1 <--> void.
Proof.
have: 'D_-1 -> void.
{
move=>[x pf].
rewrite expr0 in pf.
move: (oner_neq0 R).
by move /eqP.
}
move=> fwd.
refine ({|
Forward := fwd;
Backward := of_void _;
BF x := match fwd x with end;
FB x := match x with end;
|}).
Defined.
Definition polynomial {n} (coeffs : 'I_n -> R) (x : R) : R
:= \prod_(i < n) ((x ^+ i) * coeffs i).
(* Implementation at the bottom of the file. *)
Module Type nilpotent_properties_sig.
Axiom KL_D : forall {n}, (nilpotent n -> R) <--> ('I_n -> R).
Axiom KL_D_back : forall {n coeffs} {d : nilpotent n},
Backward _ _ KL_D coeffs d = polynomial coeffs d.
End nilpotent_properties_sig.
(* Spaces of infinitesimal vectors. *)
(* I think this space acts like a walking simplex? *)
Definition Δ n := {x : 'I_n -> R | forall i j, x i * x j = 0}.
Coercion Rn_of_Δ {n} (d : Δ n) : {ffun 'I_n -> R} := finfun (proj1_sig d).
#[refine]
Global Instance Δ_zero {n} : Zero (Δ n) := {
zero := exist _ (fun=> 0) (fun _ _ => _)
}.
exact (mul0r 0).
Defined.
Lemma eq_Δ {n} {u v : Δ n} (pf : forall i, u i = v i) : u = v.
move: u v pf => [u pf_u] [v pf_v] pf.
rewrite /Rn_of_Δ in pf; simpl in pf.
have: u = v.
{
apply: functional_extensionality => i.
move: (pf i).
by rewrite ffunE ffunE.
}
move=> tmp. move: tmp pf_v pf => <- pf_v _.
f_equal.
apply: proof_irrelevance.
Qed.
Definition Δ1_D_iso_fwd : Δ 1 -> 'D_1 :=
fun '(exist x pf) =>
exist _ (x ord0) (Logic.eq_trans (expr2 (x ord0)) (pf ord0 ord0)).
Definition Δ1_D_iso_bwd : 'D_1 -> Δ 1.
refine(fun '(exist x pf) => exist _ (fun=> x) _).
by rewrite -expr2 pf.
Defined.
Definition Δ1_D_iso : Δ 1 <--> 'D_1.
Proof.
refine ({|
Forward := Δ1_D_iso_fwd;
Backward := Δ1_D_iso_bwd;
|}).
- move=> [x pf].
apply: eq_Δ => i.
rewrite /Rn_of_Δ ffunE ffunE; simpl.
by rewrite ord1.
- move=> [x pf]; simpl.
f_equal.
apply: proof_irrelevance.
Defined.
(* Implementation at the bottom of the file. *)
Module Type Δ_properties_sig.
Axiom KL_Δ : forall {n}, (Δ n -> R) <--> (R * ('I_n -> R)).
Axiom KL_Δ_back : forall {n coeffs} {d : Δ n},
Backward _ _ KL_Δ coeffs d = fst coeffs + \sum_i snd coeffs i * d i.
End Δ_properties_sig.
(* Implementation details that involve Weil algebras *)
Require Import weil_algebras.
Module Export nilpotent_properties : nilpotent_properties_sig.
Definition nilpotent_weil_mul n
(x : {ffun 'I_n -> R^o}) (y : {ffun 'I_n -> R^o}) : {ffun 'I_n -> R^o} :=
[ffun k : 'I_n => \sum_(i < n) \sum_(j < n)
if (i + j + 1 == k)%N then x i * y j else 0
].
Fact nilpotent_weil_mul_linear n z : linear (nilpotent_weil_mul n z).
Proof.
move=> a x y.
rewrite /nilpotent_weil_mul {2}/*:%R {4}/+%R; simpl.
rewrite /ffun_scale /ffun_add.
apply: eq_ffun => k.
do 3 rewrite ffunE.
rewrite scaler_sumr -big_split; simpl.
apply: eq_bigr => i _.
rewrite scaler_sumr -big_split; simpl.
apply: eq_bigr => j _.
case: (i + j + 1 == k)%N.
+ rewrite scalerAr -mulrDr.
rewrite {1}/*:%R {1}/+%R; simpl.
by rewrite /ffun_scale /ffun_add ffunE ffunE.
+ by rewrite addr0 scaler0.
Qed.
Fact nilpotent_weil_mul_assoc n : associative (nilpotent_weil_mul n).
Proof.
move=> x y z.
apply: eq_ffun => k.
suff: (\sum_(i < n)\sum_(j < n)\sum_(i' < n)\sum_(j' < n)
if (i + j + 1 == k)%N && (i' + j' + 1 == j)%N then x i * y i' * z j' else 0)
= (\sum_(i < n)\sum_(j < n)\sum_(i' < n)\sum_(j' < n)
if (i + j + 1 == k)%N && (i' + j' + 1 == i)%N then x i' * y j' * z j else 0).
{
move=> eq.
apply: Logic.eq_trans; first (apply: Logic.eq_trans; last apply: eq).
- apply: eq_bigr => i _.
apply: eq_bigr => j _.
case: (i + j + 1 == k)%N.
+ rewrite ffunE mulr_sumr.
apply: eq_bigr => i' _.
rewrite mulr_sumr.
apply: eq_bigr => j' _.
case: (i' + j' + 1 == j)%N; simpl.
* by rewrite mulrA.
* by rewrite mulr0.
+ rewrite big1; first done.
move=> i' _.
by rewrite big1.
- apply: eq_bigr => i _.
apply: eq_bigr => j _.
case: (i + j + 1 == k)%N.
+ rewrite ffunE mulr_suml.
apply: eq_bigr => i' _.
rewrite mulr_suml.
apply: eq_bigr => j' _.
case: (i' + j' + 1 == i)%N; simpl.
* done.
* by rewrite mul0r.
+ rewrite big1; first done.
move=> i' _.
by rewrite big1.
}
have: forall (P : 'I_n -> bool) F, (forall a b, P a -> P b -> a = b)
-> (\sum_(i | P i) F i) = if [pick x | P x] is Some x then F x else 0.
{
move=> t P F eq.
case pickP.
- move=> i pf.
apply: big_pred1.
move=> j.
apply/idP/eqP.
+ move=> pf2.
by apply: eq.
+ by move=>->.
- move=> H.
by apply: big_pred0.
}
move=> lemma.
suff: (\sum_(i < n)\sum_(i' < n)\sum_(j' < n)
if (i + (i' + j' + 1) + 1 == k)%N then x i * y i' * z j' else 0)
= (\sum_(j < n)\sum_(i' < n)\sum_(j' < n)
if ((i' + j' + 1) + j + 1 == k)%N then x i' * y j' * z j else 0).
{
move=> eq.
apply: Logic.eq_trans; first (apply: Logic.eq_trans; last apply: eq).
- apply: eq_bigr => i _.
rewrite exchange_big; apply: eq_bigr => i' _.
rewrite exchange_big; apply: eq_bigr => j' _.
rewrite -big_mkcond.
rewrite lemma.
+ case pickP.
* move=> j /andP [/eqP <- /eqP <-].
by case eqP.
* case: eqP; last done.
move=> eq2.
suff: (i' + j' + 1)%N < n.
{
move=> less nope.
suff: false by [].
rewrite -(nope (Ordinal less)) -eq2; simpl.
by apply /andP.
}
apply: leq_ltn_trans; last exact: ltn_ord k.
rewrite -eq2.
apply: leq_trans; [apply: leq_addl | apply: leq_addr].
+ move=> [a a_pf] [b b_pf] /andP [/eqP <- /eqP ->] /andP [_ /eqP eq2].
simpl in eq2.
move: eq2 a_pf => -> a_pf.
f_equal.
apply: proof_irrelevance.
- apply: Logic.eq_sym.
rewrite exchange_big; apply: eq_bigr => j _.
rewrite exchange_big; apply: eq_bigr => i' _.
rewrite exchange_big; apply: eq_bigr => j' _.
rewrite -big_mkcond.
rewrite lemma.
+ case pickP.
* move=> i /andP [/eqP <- /eqP <-].
by case eqP.
* case: eqP; last done.
move=> eq2.
suff: (i' + j' + 1)%N < n.
{
move=> less nope.
suff: false by [].
rewrite -(nope (Ordinal less)) -eq2; simpl.
by apply /andP.
}
apply: leq_ltn_trans; last exact: ltn_ord k.
rewrite -eq2.
apply: leq_trans; [apply: leq_addr | apply: leq_addr].
+ move=> [a a_pf] [b b_pf] /andP [/eqP <- /eqP ->] /andP [_ /eqP eq2].
simpl in eq2.
move: eq2 a_pf => -> a_pf.
f_equal.
apply: proof_irrelevance.
}
apply: Logic.eq_sym.
rewrite exchange_big; apply: eq_bigr => i _.
rewrite exchange_big; apply: eq_bigr => i' _.
apply: eq_bigr => j' _.
suff: (i + i' + 1 + j')%N = (i + (i' + j' + 1))%N by move=>->.
do 3 rewrite -addnA; f_equal; f_equal.
apply: addnC.
Qed.
Fact nilpotent_weil_mul_comm n : commutative (nilpotent_weil_mul n).
Proof.
move=> x y.
apply: eq_ffun => k.
rewrite exchange_big.
apply: eq_bigr => i _.
apply: eq_bigr => j _.
move: (addnC j i) => ->.
move: (mulrC (x j) (y i)) => ->.
done.
Qed.
Fact nilpotent_weil_mul_nilpotent n x (xs : 'I_n -> _)
: \big[nilpotent_weil_mul n/x]_i xs i = 0.
Proof.
move: xs.
suff: forall m xs (mn : m <= n) (i : 'I_n), i < m ->
(\big[nilpotent_weil_mul n/x]_(j : 'I_m) xs j) i = 0.
{
move=> H xs.
rewrite -ffunP => i.
rewrite (H n xs (leqnn n) i (ltn_ord i)).
by rewrite /0; simpl; rewrite /ffun_zero ffunE.
}
elim=> [|m IH] xs mn k pf.
- done.
- rewrite big_ord_recl ffunE.
rewrite big1; first done.
move=> i _.
rewrite big1; first done.
move=> j _.
case eqP; last done.
move=> eq.
suff: (\big[nilpotent_weil_mul n/x]_(i0 < m)
xs (lift ord0 i0)) j = 0.
{
move=>->.
apply: mulr0.
}
apply: IH.
- by apply: ltnW.
- rewrite -ltnS.
apply: leq_ltn_trans; last apply: pf.
move: eq => <-.
rewrite addn1.
apply leq_addl.
Qed.
Definition nilpotent_weil (n : nat) : WeilData R := {|
Domain := [finType of 'I_n];
Mul := nilpotent_weil_mul n;
Lin := nilpotent_weil_mul_linear n;
Assoc := nilpotent_weil_mul_assoc n;
Comm := nilpotent_weil_mul_comm n;
Nilpotent := ex_intro _ _ (nilpotent_weil_mul_nilpotent n);
|}.
Definition nilpotent_weil_iso {n} : 'D_n <--> Spec R (Weil (nilpotent_weil n)).
apply: iso_trans; last apply: reifyIso.
refine({|
Forward '(exist x pf) := exist _ [ffun i => x] _;
Backward '(exist f morph) := exist _ (\sum_i f i) _;
|}).
Admitted.
Definition KL_D {n} : (nilpotent n -> R) <--> ('I_n -> R).
Admitted.
Theorem KL_D_back {n coeffs} {d : nilpotent n}
: Backward _ _ KL_D coeffs d = polynomial coeffs d.
Admitted.
End nilpotent_properties.
Module Export Δ_properties : Δ_properties_sig.
Definition Δ_weil (n : nat) : WeilData R.
Proof.
refine ({|
Domain := [finType of 'I_n];
Mul := fun _ _ => 0;
Lin := fun _ _ _ _ => Logic.eq_sym (Logic.eq_trans (addr0 _) (scaler0 _ _));
Assoc := fun _ _ _ => Logic.eq_refl;
Comm := fun _ _ => Logic.eq_refl;
Nilpotent := ex_intro _ [finType of 'I_1] _
|}).
move=> x xs.
apply: big_ord_recl.
Defined.
Definition KL_Δ {n} : (Δ n -> R) <--> (R * ('I_n -> R)).
Admitted.
Theorem KL_Δ_back {n coeffs} {d : Δ n}
: Backward _ _ KL_Δ coeffs d = fst coeffs + \sum_i snd coeffs i * d i.
Admitted.
End Δ_properties.