Skip to content

Commit 923ff6e

Browse files
dhsorenskatyhr
authored andcommitted
UniPoly equivalence relation and quotient operations (Verified-zkEVM#106)
* feat: prove equiv_trans for arrays; uses unproved helper lemma matchSize_eq_iff_forall_eq which is analogous to the yet unproved analogous lemma for lists matchSize_eq_iff_forall_eq * feat: initial organization of definitions and lemmas for defining operations on the quotient polynomial type descended from the univariant polynomial type. left some TODOs * feat: defined functions for add, sub, and neg that will be lifted * feat: first proofs that add, sub, and neg descend thru the quotient. relies on small lemma left as TODO * fix: improve lemmas * feat: refine the lemmas about the relationship between equivalence and operations on UniPoly * feat: redefine equiv to be Trim.equiv bc of existing theory * fix: prove lemma that neg and coeff commute * fix: accidentally deleted popWhile_nil_or_last_false * fix: in response to gh feedback, simplify the logic of the proofs of add_descends and neg_descends * cleanup: remove superfluous open list
1 parent ea42d72 commit 923ff6e

1 file changed

Lines changed: 83 additions & 20 deletions

File tree

ArkLib/Data/UniPoly/Basic.lean

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,16 @@ theorem add_coeff? (p q : UniPoly Q) (i : ℕ) :
583583
have h_q : i ≥ q.size := by omega
584584
simp [h_ge, h_p, h_q]
585585

586+
lemma add_equiv_raw [LawfulBEq R] (p q : UniPoly R) : Trim.equiv (p.add q) (p.add_raw q) := by
587+
unfold Trim.equiv add
588+
exact Trim.coeff_eq_coeff (p.add_raw q)
589+
590+
omit [BEq R] in
591+
lemma neg_coeff : ∀ (p : UniPoly R) (i : ℕ), p.neg.coeff i = - p.coeff i := by
592+
intro p i
593+
unfold neg coeff
594+
rcases (Nat.lt_or_ge i p.size) with hi | hi <;> simp [hi]
595+
586596
lemma trim_add_trim [LawfulBEq R] (p q : UniPoly R) : p.trim + q = p + q := by
587597
apply Trim.eq_of_equiv
588598
intro i
@@ -875,32 +885,21 @@ lemma eval_trim_eq_eval [LawfulBEq R] (x : R) (p : UniPoly R) : p.trim.eval x =
875885
end ToPoly
876886

877887
section Equiv
878-
879-
/-- An equivalence relation `equiv` on `UniPoly`s where `p ~ q` iff one is a
880-
zero-padding of the other. -/
881-
def equiv (p q : UniPoly R) : Prop :=
882-
match p.matchSize q 0 with
883-
| (p', q') => p' = q'
888+
open Trim
884889

885890
/-- Reflexivity of the equivalence relation. -/
886891
@[simp] theorem equiv_refl (p : UniPoly Q) : equiv p p :=
887892
by simp [equiv]
888893

889894
/-- Symmetry of the equivalence relation. -/
890-
@[simp] theorem equiv_symm {p q : UniPoly Q} : equiv p q → equiv q p :=
891-
fun h => by simp [equiv] at *; exact Eq.symm h
895+
@[simp] theorem equiv_symm {p q : UniPoly Q} : equiv p q → equiv q p := by
896+
simp [equiv]
897+
intro h i
898+
exact Eq.symm (h i)
892899

893-
open List in
894900
/-- Transitivity of the equivalence relation. -/
895-
@[simp] theorem equiv_trans {p q r : UniPoly Q} : equiv p q → equiv q r → equiv p r :=
896-
fun hpq hqr => by
897-
simp_all [equiv]
898-
sorry
899-
-- have hpq' := (List.matchSize_eq_iff_forall_eq p.toList q.toList 0).mp hpq
900-
-- have hqr' := (List.matchSize_eq_iff_forall_eq q.toList r.toList 0).mp hqr
901-
-- have hpr' : ∀ (i : Nat), p.toList.getD i 0 = r.toList.getD i 0 :=
902-
-- fun i => Eq.trans (hpq' i) (hqr' i)
903-
-- exact (List.matchSize_eq_iff_forall_eq p.toList r.toList 0).mpr hpr'
901+
@[simp] theorem equiv_trans {p q r : UniPoly Q} : Trim.equiv p q → equiv q r → equiv p r := by
902+
simp_all [Trim.equiv]
904903

905904
/-- The `UniPoly.equiv` is indeed an equivalence relation. -/
906905
instance instEquivalenceEquiv : Equivalence (equiv (R := R)) where
@@ -915,11 +914,75 @@ instance instSetoidUniPoly: Setoid (UniPoly R) where
915914

916915
/-- The quotient of `UniPoly R` by `UniPoly.equiv`. This will be changen to be equivalent to
917916
`Polynomial R`. -/
918-
def QuotientUniPoly := Quotient (@instSetoidUniPoly R _)
917+
def QuotientUniPoly (R : Type*) [Ring R] [BEq R] := Quotient (@instSetoidUniPoly R _)
918+
919+
-- operations on `UniPoly` descend to `QuotientUniPoly`
920+
namespace QuotientUniPoly
921+
922+
-- Addition: add descends to `QuotientUniPoly`
923+
def add_descending (p q : UniPoly R) : QuotientUniPoly R :=
924+
Quotient.mk _ (add p q)
925+
926+
lemma add_descends [LawfulBEq R] (a₁ b₁ a₂ b₂ : UniPoly R) :
927+
equiv a₁ a₂ → equiv b₁ b₂ → add_descending a₁ b₁ = add_descending a₂ b₂ := by
928+
intros heq_a heq_b
929+
unfold add_descending
930+
rw [Quotient.eq]
931+
simp [instSetoidUniPoly]
932+
calc
933+
add a₁ b₁ ≈ add_raw a₁ b₁ := add_equiv_raw a₁ b₁
934+
_ ≈ add_raw a₂ b₂ := by
935+
intro i
936+
rw [add_coeff? a₁ b₁ i, add_coeff? a₂ b₂ i, heq_a i, heq_b i]
937+
_ ≈ add a₂ b₂ := equiv_symm (add_equiv_raw a₂ b₂)
919938

920-
-- TODO: change that operations on `UniPoly` descend to `QuotientUniPoly`
939+
@[inline, specialize]
940+
def add {R : Type*} [Ring R] [BEq R] [LawfulBEq R] (p q : QuotientUniPoly R) : QuotientUniPoly R :=
941+
Quotient.lift₂ add_descending add_descends p q
942+
943+
-- Negation: neg descends to `QuotientUniPoly`
944+
def neg_descending (p : UniPoly R) : QuotientUniPoly R :=
945+
Quotient.mk _ (neg p)
946+
947+
lemma neg_descends (a b : UniPoly R) : equiv a b → neg_descending a = neg_descending b := by
948+
unfold equiv neg_descending
949+
intros heq
950+
rw [Quotient.eq]
951+
simp [instSetoidUniPoly]
952+
unfold equiv
953+
intro i
954+
rw [neg_coeff a i, neg_coeff b i, heq i]
955+
956+
@[inline, specialize]
957+
def neg {R : Type*} [Ring R] [BEq R] (p : QuotientUniPoly R) : QuotientUniPoly R :=
958+
Quotient.lift neg_descending neg_descends p
959+
960+
-- Subtraction: sub descends to `QuotientUniPoly`
961+
def sub_descending (p q : UniPoly R) : QuotientUniPoly R :=
962+
Quotient.mk _ (sub p q)
963+
964+
lemma sub_descends [LawfulBEq R] (a₁ b₁ a₂ b₂ : UniPoly R) :
965+
equiv a₁ a₂ → equiv b₁ b₂ → sub_descending a₁ b₁ = sub_descending a₂ b₂ := by
966+
unfold equiv sub_descending
967+
intros heq_a heq_b
968+
rw [Quotient.eq]
969+
simp [instSetoidUniPoly]
970+
unfold sub equiv
971+
calc
972+
a₁.add b₁.neg ≈ a₁.add_raw b₁.neg := add_equiv_raw a₁ b₁.neg
973+
_ ≈ a₂.add_raw b₂.neg := by
974+
intro i
975+
rw [add_coeff? a₁ b₁.neg i, add_coeff? a₂ b₂.neg i]
976+
rw [neg_coeff b₁ i, neg_coeff b₂ i, heq_a i, heq_b i]
977+
_ ≈ a₂.add b₂.neg := equiv_symm (add_equiv_raw a₂ b₂.neg)
978+
979+
@[inline, specialize]
980+
def sub {R : Type*} [Ring R] [BEq R] [LawfulBEq R] (p q : QuotientUniPoly R) : QuotientUniPoly R :=
981+
Quotient.lift₂ sub_descending sub_descends p q
921982

983+
-- TODO the other operations ...
922984

985+
end QuotientUniPoly
923986

924987
end Equiv
925988

0 commit comments

Comments
 (0)