@@ -715,15 +715,42 @@ split.
715715apply phi_decomp.
716716Qed .
717717
718- Lemma a23: forall (U : Square 4), WF_Unitary U -> (forall (x : Vector 2), TensorProdQubit (U × (x ⊗ ∣0⟩))) ->
719- (exists (psi: Vector 2), forall (x: Vector 2), WF_Matrix x -> exists (z: Vector 2), U × (x ⊗ ∣0⟩) = z ⊗ psi)
720- \/
721- (exists (psi: Vector 2), forall (x: Vector 2), WF_Matrix x -> exists (z: Vector 2), U × (x ⊗ ∣0⟩) = psi ⊗ z).
722- Proof .
718+ Lemma a23 : forall (U : Square 4), WF_Unitary U ->
719+ (forall (x : Vector 2), WF_Qubit x -> TensorProdQubit (U × (x ⊗ ∣0⟩))) ->
720+ (exists (psi: Vector 2), WF_Qubit psi /\
721+ forall (x: Vector 2), WF_Qubit x ->
722+ exists (z: Vector 2), WF_Qubit z /\ U × (x ⊗ ∣0⟩) = z ⊗ psi) \/
723+ (exists (psi: Vector 2), WF_Qubit psi /\
724+ forall (x: Vector 2), WF_Qubit x ->
725+ exists (z: Vector 2), WF_Qubit z /\ U × (x ⊗ ∣0⟩) = psi ⊗ z).
726+ Proof .
723727intros U U_unitary tensorProp.
724- assert (ts0 : TensorProdQubit (U × (∣0⟩ ⊗ ∣0⟩))). apply tensorProp.
725- assert (ts1 : TensorProdQubit (U × (∣1⟩ ⊗ ∣0⟩))). apply tensorProp.
726- assert (tsp : TensorProdQubit (U × (∣+⟩ ⊗ ∣0⟩))). apply tensorProp.
728+ assert (ts0 : TensorProdQubit (U × (∣0⟩ ⊗ ∣0⟩))). apply tensorProp, qubit0_qubit.
729+ assert (ts1 : TensorProdQubit (U × (∣1⟩ ⊗ ∣0⟩))). apply tensorProp, qubit1_qubit.
730+ assert (tsp : TensorProdQubit (U × (∣+⟩ ⊗ ∣0⟩))).
731+ {
732+ apply tensorProp.
733+ (* TODO(Kyle): This should be a separate lemma like qubit0_qubit *)
734+ unfold WF_Qubit.
735+ split.
736+ {
737+ exists 1%nat.
738+ compute.
739+ reflexivity.
740+ }
741+ split.
742+ {
743+ solve_WF_matrix.
744+ }
745+ {
746+ unfold inner_product.
747+ unfold xbasis_plus.
748+ unfold Mplus, Mmult, scale, adjoint; simpl; Csimpl.
749+ replace ((/ √ 2) ^*) with (/ √ 2) by lca.
750+ rewrite Cinv_sqrt2_sqrt.
751+ lca.
752+ }
753+ }
727754unfold TensorProdQubit in ts0, ts1, tsp.
728755assert (WF_Matrix (U × (∣0⟩ ⊗ ∣0⟩))). solve_WF_matrix.
729756apply ts0 in H. clear ts0.
@@ -821,9 +848,71 @@ destruct casework as [blindep|alindep].
821848 destruct proportional as [c lindepeq].
822849 left.
823850 exists b0.
824- intros x WF_x.
851+ split. exact b0_qubit.
852+ intros x x_qubit.
825853 exists (x 0%nat 0%nat .* a0 .+ x 1%nat 0%nat .* (c .* a1)).
826- rewrite qubit_decomposition1 with (phi:= x) at 1. 2: assumption.
854+ (* TODO(Kyle): Show that this is a qubit! *)
855+ assert (WF_Qubit (x 0%nat 0%nat .* a0 .+ x 1%nat 0%nat .* (c .* a1))).
856+ {
857+ unfold WF_Qubit.
858+ {
859+ split.
860+ {
861+ exists 1%nat.
862+ compute.
863+ reflexivity.
864+ }
865+ split.
866+ {
867+ solve_WF_matrix.
868+ }
869+ {
870+ (* TODO: Move me somewhere else! *)
871+ (* TODO: Make me more general! *)
872+ assert (inner_product_kron : forall {m n} (u : Vector m) (v : Vector n),
873+ ⟨u ⊗ v, u ⊗ v⟩ = ⟨u, u⟩ * ⟨v, v⟩).
874+ {
875+ intros.
876+ unfold inner_product.
877+ rewrite (@kron_adjoint m 1 n 1).
878+ rewrite (@kron_mixed_product 1 m 1 1 n 1).
879+ unfold kron; reflexivity.
880+ }
881+ assert (U × (x ⊗ ∣0⟩) = (x 0%nat 0%nat .* a0 .+ x 1%nat 0%nat .* (c .* a1)) ⊗ b0).
882+ {
883+ rewrite qubit_decomposition1 with (phi:= x) at 1. 2: apply x_qubit.
884+ rewrite kron_plus_distr_r.
885+ rewrite Mmult_plus_distr_l.
886+ do 2 rewrite Mscale_kron_dist_l.
887+ do 2 rewrite Mscale_mult_dist_r.
888+ assert (def_help: (U × (∣0⟩ ⊗ ∣0⟩)) = a0 ⊗ b0). apply a0b0_def.
889+ rewrite def_help at 1. clear def_help.
890+ assert (def_help: (U × (∣1⟩ ⊗ ∣0⟩)) = a1 ⊗ b1). apply a1b1_def.
891+ rewrite def_help at 1. clear def_help.
892+ rewrite <- lindepeq.
893+ rewrite kron_plus_distr_r.
894+ repeat rewrite Mscale_kron_dist_l.
895+ repeat rewrite Mscale_kron_dist_r.
896+ reflexivity.
897+ }
898+ rewrite <- Cmult_1_r at 1.
899+ rewrite <- b0_unit at 1.
900+ rewrite <- inner_product_kron.
901+ rewrite <- H.
902+ rewrite inner_product_adjoint_l.
903+ destruct U_unitary as [WF_U U_unitary].
904+ rewrite <- Mmult_assoc.
905+ rewrite U_unitary at 1.
906+ rewrite Mmult_1_l; solve_WF_matrix.
907+ rewrite (@inner_product_kron 2 2)%nat.
908+ destruct x_qubit as [_ [WF_x x_unit]].
909+ rewrite x_unit.
910+ unfold inner_product, qubit0, adjoint, Mmult; lca.
911+ }
912+ }
913+ }
914+ split. assumption.
915+ rewrite qubit_decomposition1 with (phi:= x) at 1. 2: apply x_qubit.
827916 rewrite kron_plus_distr_r.
828917 rewrite Mmult_plus_distr_l.
829918 do 2 rewrite Mscale_kron_dist_l.
@@ -912,9 +1001,70 @@ destruct casework as [blindep|alindep].
9121001 destruct proportional as [c prop].
9131002 right.
9141003 exists a0.
915- intros x WF_x.
1004+ split. exact a0_qubit.
1005+ intros x x_qubit.
9161006 exists (x 0%nat 0%nat .* b0 .+ x 1%nat 0%nat .* (c .* b1)).
917- rewrite qubit_decomposition1 with (phi:= x) at 1. 2: assumption.
1007+ assert (WF_Qubit (x 0%nat 0%nat .* b0 .+ x 1%nat 0%nat .* (c .* b1))).
1008+ {
1009+ unfold WF_Qubit.
1010+ {
1011+ split.
1012+ {
1013+ exists 1%nat.
1014+ compute.
1015+ reflexivity.
1016+ }
1017+ split.
1018+ {
1019+ solve_WF_matrix.
1020+ }
1021+ {
1022+ (* TODO: Move me somewhere else! *)
1023+ (* TODO: Make me more general! *)
1024+ assert (inner_product_kron : forall {m n} (u : Vector m) (v : Vector n),
1025+ ⟨u ⊗ v, u ⊗ v⟩ = ⟨u, u⟩ * ⟨v, v⟩).
1026+ {
1027+ intros.
1028+ unfold inner_product.
1029+ rewrite (@kron_adjoint m 1 n 1).
1030+ rewrite (@kron_mixed_product 1 m 1 1 n 1).
1031+ unfold kron; reflexivity.
1032+ }
1033+ assert (U × (x ⊗ ∣0⟩) = a0 ⊗ (x 0%nat 0%nat .* b0 .+ x 1%nat 0%nat .* (c .* b1))).
1034+ {
1035+ rewrite qubit_decomposition1 with (phi:= x) at 1. 2: apply x_qubit.
1036+ rewrite kron_plus_distr_r.
1037+ rewrite Mmult_plus_distr_l.
1038+ do 2 rewrite Mscale_kron_dist_l.
1039+ do 2 rewrite Mscale_mult_dist_r.
1040+ assert (def_help: (U × (∣0⟩ ⊗ ∣0⟩)) = a0 ⊗ b0). apply a0b0_def.
1041+ rewrite def_help at 1. clear def_help.
1042+ assert (def_help: (U × (∣1⟩ ⊗ ∣0⟩)) = a1 ⊗ b1). apply a1b1_def.
1043+ rewrite def_help at 1. clear def_help.
1044+ rewrite <- prop.
1045+ rewrite kron_plus_distr_l.
1046+ repeat rewrite Mscale_kron_dist_l.
1047+ repeat rewrite Mscale_kron_dist_r.
1048+ reflexivity.
1049+ }
1050+ rewrite <- Cmult_1_l at 1.
1051+ rewrite <- a0_unit at 1.
1052+ rewrite <- inner_product_kron.
1053+ rewrite <- H.
1054+ rewrite inner_product_adjoint_l.
1055+ destruct U_unitary as [WF_U U_unitary].
1056+ rewrite <- Mmult_assoc.
1057+ rewrite U_unitary at 1.
1058+ rewrite Mmult_1_l; solve_WF_matrix.
1059+ rewrite (@inner_product_kron 2 2)%nat.
1060+ destruct x_qubit as [_ [WF_x x_unit]].
1061+ rewrite x_unit.
1062+ unfold inner_product, qubit0, adjoint, Mmult; lca.
1063+ }
1064+ }
1065+ }
1066+ split. assumption.
1067+ rewrite qubit_decomposition1 with (phi:= x) at 1. 2: apply x_qubit.
9181068 rewrite kron_plus_distr_r.
9191069 rewrite Mmult_plus_distr_l.
9201070 do 2 rewrite Mscale_kron_dist_l.
0 commit comments