@@ -3,6 +3,7 @@ Require Import QuantumLib.Polynomial.
33Require Import QuantumLib.Matrix.
44Require Import QuantumLib.Quantum.
55Require Import QuantumLib.Eigenvectors.
6+ Require Import QuantumLib.Permutations.
67Require Import MatrixHelpers.
78Require Import DiagonalHelpers.
89Require Import UnitaryHelpers.
@@ -11,6 +12,14 @@ Require Import Setoid.
1112
1213Module P := Polynomial.
1314
15+ (* Given an assumption H : A -> B, prove A then specialize H with that proof, yielding H : B. *)
16+ Ltac forward H :=
17+ match type of H with
18+ | (?A -> ?B) =>
19+ let H1 := fresh "H" in
20+ assert (H1 : A); [ | specialize (H H1); clear H1]
21+ end .
22+
1423(* Open the polynomial scope *)
1524Local Open Scope poly_scope.
1625
@@ -72,16 +81,16 @@ Fixpoint big_prod (f : nat -> C) (n : nat) : C :=
7281 end .
7382
7483Lemma complex_poly_degree : forall (q : Polynomial) (d : C),
75- Peval (q *, [d; -C1]) <> Peval [C1].
84+ Peval ([d; -C1] *, q ) <> Peval [C1].
7685Proof .
7786 intros q d Heq'.
7887 apply degree_mor in Heq' as Hdeg.
79- assert (Heq : (q *, [d; - C1]) ≅ [C1]) by apply Heq'.
88+ assert (Heq : ([d; - C1] *, q ) ≅ [C1]) by apply Heq'.
8089 unfold degree at 2 in Hdeg.
8190 unfold compactify in Hdeg.
82- simpl in Hdeg.
91+ simpl length in Hdeg.
8392 destruct (Ceq_dec C1 C0) as [H01 | _]; try (inversion H01; lra).
84- simpl in Hdeg.
93+ simpl rev in Hdeg.
8594 assert (H_nil_neq_1 : ~ ([] ≅ [C1])).
8695 { intro H_nil_1.
8796 assert ([][[0]] = [C1][[0]]) by now rewrite H_nil_1.
@@ -90,14 +99,14 @@ Proof.
9099 assert (Hq_neq_nil : ~ (q ≅ [])).
91100 { intro H_qnil.
92101 setoid_rewrite H_qnil in Heq.
93- now simpl in Heq.}
102+ now rewrite P.Pmult_0_r in Heq. }
94103 assert (Hdx_neq_nil : ~ ([d; - C1] ≅ [])).
95104 { intro H_dxnil.
96105 setoid_rewrite H_dxnil in Heq.
97- now rewrite P.Pmult_0_r in Heq.}
98- rewrite (Pmult_degree _ _ Hq_neq_nil Hdx_neq_nil) in Hdeg.
106+ now simpl in Heq. }
107+ rewrite (Pmult_degree _ _ Hdx_neq_nil Hq_neq_nil ) in Hdeg.
99108
100- unfold degree at 2 in Hdeg.
109+ unfold degree at 1 in Hdeg.
101110 unfold compactify in Hdeg.
102111 simpl in Hdeg.
103112 destruct (Ceq_dec (-C1) 0) as [H01 | _]; try (inversion H01; lra).
106115
107116(* Lemma 1.1 (Euclid's Lemma) *)
108117Lemma euclid_lemma : forall {d e : C} {p r : Polynomial},
109- p *, [d; -C1] ≅ r *, [e; -C1] ->
110- d = e \/ exists (q : Polynomial), q *, [d; -C1] ≅ r.
118+ [d; -C1] *, p ≅ r *, [e; -C1] ->
119+ d = e \/ exists (q : Polynomial), [d; -C1] *, q ≅ r.
111120Proof .
112121 (* TODO: the polynomial theorem names collide with Coq.PArith *)
113122
@@ -117,8 +126,10 @@ Proof.
117126
118127 (* construct 1/(d - e) * (r - p) *)
119128 exists ([/ (d - e)] *, (r +, -,p)).
129+ rewrite P.Pmult_comm.
120130 rewrite P.Pmult_assoc.
121131 rewrite P.Pmult_plus_distr_r.
132+ rewrite P.Pmult_comm in Heq.
122133 unfold Popp.
123134 rewrite P.Pmult_assoc, Heq.
124135 rewrite <- P.Pmult_assoc.
145156Lemma poly_isolate_factor : forall (d : C) (facs : list C),
146157 facs <> [] ->
147158 (forall (p : Polynomial),
148- p *, [d; -C1] ≅ poly_prod facs ->
159+ [d; -C1] *, p ≅ poly_prod facs ->
149160 exists (k : nat), nth_error facs k = Some d).
150161Proof .
151162 intros d facs.
@@ -164,8 +175,7 @@ Proof.
164175 now apply complex_poly_degree in Hex.
165176
166177 - intros _ p0 Heq.
167- assert (H0 : f0 :: facs <> []) by easy.
168- specialize (IH H0); clear H0.
178+ forward IH. { easy. }
169179 setoid_replace
170180 (poly_prod (f :: f0 :: facs)) with
171181 ([f; -C1] *, poly_prod (f0 :: facs))
@@ -184,3 +194,109 @@ Proof.
184194 exists (S k).
185195 auto.
186196Qed .
197+
198+ Lemma singleton_list : forall {T} {l : list T},
199+ (length l = 1)%nat -> exists x, l = [x].
200+ Proof .
201+ intros.
202+ destruct l; try inversion H.
203+ destruct l; try inversion H1.
204+
205+ now exists t.
206+ Qed .
207+
208+ Lemma poly_prod_middle : forall (l1 l2 : Factors) (f : C), poly_prod (l1 ++ f :: l2) ≅ poly_prod (f :: l1 ++ l2).
209+ Proof .
210+ intro l1.
211+ induction l1; try reflexivity.
212+ intros l2 f.
213+ simpl app.
214+ unfold poly_prod.
215+ fold poly_prod.
216+ rewrite IHl1.
217+ unfold poly_prod.
218+ fold poly_prod.
219+ rewrite <- P.Pmult_assoc.
220+ rewrite <- P.Pmult_assoc.
221+ now rewrite (P.Pmult_comm [a; -C1] [f; -C1]).
222+ Qed .
223+
224+ Lemma roots_equal_implies_permutation :
225+ forall (n : nat),
226+ (n > 0)%nat ->
227+ forall (ds es: list C),
228+ length ds = n -> length es = n ->
229+ (poly_prod ds ≅ poly_prod es) ->
230+ exists f, permutation n f /\ (forall i, ds !! i = es !! f i).
231+ Proof .
232+ intros n.
233+ induction n; try lia.
234+ (* intros. *)
235+ intros H ds es Hdlen Helen Hpeq.
236+ destruct n as [| n].
237+ - exists idn.
238+ split.
239+ + (* Permutation *)
240+ apply idn_permutation.
241+ + (* perm_pair_eq *)
242+ destruct (singleton_list Hdlen) as [delem Hd].
243+ destruct (singleton_list Helen) as [eelem He].
244+ subst.
245+ destruct i.
246+ -- unfold poly_prod in Hpeq.
247+ simpl; f_equal.
248+ simpl in Hpeq.
249+ apply Peq_head_eq in Hpeq.
250+ (* Done, just dont wanna do manual math *)
251+ admit.
252+ -- easy.
253+ - clear H.
254+ forward IHn. { lia. }
255+ destruct ds as [| d ds]; try easy.
256+ assert (Heneqnil : es <> []).
257+ { intro Hcontra.
258+ subst. easy. }
259+ destruct (poly_isolate_factor d es Heneqnil (poly_prod ds) Hpeq) as [k Hk].
260+ clear Heneqnil.
261+
262+ (* break 'es' into multiple pieces *)
263+ destruct (nth_error_split es k Hk) as [e1 [e2 [Hcombine Hidx] ] ].
264+ rewrite Hcombine in Hpeq.
265+
266+ rewrite poly_prod_middle in Hpeq.
267+ unfold poly_prod in Hpeq. fold poly_prod in Hpeq.
268+
269+ specialize (IHn ds (e1 ++ e2)).
270+ forward IHn. { auto. }
271+ forward IHn.
272+ { rewrite Hcombine in Helen.
273+ rewrite app_length in *.
274+ simpl in Helen.
275+ lia. }
276+
277+ (* We need rcancel_mul for polynomials *)
278+ assert (Hpeq' : poly_prod ds ≅ poly_prod (e1 ++ e2)). { admit. }
279+ clear Hpeq.
280+ forward IHn. { easy. }
281+ destruct IHn as [f [Hperm Hpermeq] ].
282+
283+ exists (fun i =>
284+ if i =? 0 then k else
285+ let i' := f i in
286+ if k <=? i' then i'
287+ else (i' + 1)%nat).
288+
289+ (* need inverse of f0 *)
290+ split. { admit. }
291+
292+ unfold permutation.
293+ intros i.
294+ destruct i as [| i']; try auto.
295+ subst.
296+ simpl.
297+ rewrite Hpermeq.
298+ bdestruct (length e1 <=? f (S i'))%nat.
299+ + Search lt.
300+ Search nth_error.
301+ Check nth_error_app1.
302+ rewrite (nth_error_app2 e1 (d :: e2) H).
0 commit comments