Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polynorm proofs #124

Merged
merged 15 commits into from
Sep 30, 2024
131 changes: 119 additions & 12 deletions Smt/Reconstruct/Int/Polynorm.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Copyright (c) 2021-2024 by the authors listed in the file AUTHORS and their
institutional affiliations. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Abdalrhman Mohamed
Authors: Abdalrhman Mohamed, Harun Khan
-/

import Lean
Expand Down Expand Up @@ -60,8 +60,52 @@ def denote (ctx : Context) (m : Monomial) : Int :=
theorem denote_neg {m : Monomial} : m.neg.denote ctx = -m.denote ctx := by
simp only [neg, denote, Int.neg_mul_eq_neg_mul]

theorem denote_mul {m₁ m₂ : Monomial} : (m₁.mul m₂).denote ctx = m₁.denote ctx * m₂.denote ctx :=
sorry
section

variable {op : α → α → α} (assoc : ∀ a b c, op (op a b) c = op a (op b c))

-- Can be generalized to `List.foldl_assoc`.
theorem foldl_assoc {g : β → α} (z1 z2 : α) :
List.foldl (fun z a => op z (g a)) (op z1 z2) l =
op z1 (List.foldl (fun z a => op z (g a)) z2 l) := by
induction l generalizing z1 z2 with
| nil => rfl
| cons y ys ih =>
simp only [List.foldl_cons, ih, assoc]

theorem foldr_assoc {g : β → α} (z1 z2 : α) :
List.foldr (fun z a => op a (g z)) (op z1 z2) l =
op z1 (List.foldr (fun z a => op a (g z)) z2 l) := by
induction l generalizing z1 z2 with
| nil => rfl
| cons y ys ih =>
simp only [List.foldr_cons, ih, assoc]

end
-- Can be generazlized.
theorem foldl_mul_insert {ctx : Context} :
List.foldl (fun z a => z * (ctx a)) 1 (mul.insert y ys) =
(ctx y) * List.foldl (fun z a => z * (ctx a)) 1 ys := by
induction ys with
| nil => simp [List.foldl]
| cons x ys ih =>
by_cases h : y ≤ x
· simp [mul.insert, h, foldl_assoc Int.mul_assoc (ctx y) (ctx x), Int.mul_assoc]
· simp only [mul.insert, h, List.foldl_cons, ite_false, Int.mul_comm,
foldl_assoc Int.mul_assoc, ih]
rw [←Int.mul_assoc, Int.mul_comm (ctx x) (ctx y), Int.mul_assoc]

theorem denote_add {m n : Monomial} (h : m.vars = n.vars) :
(m.add n h).denote ctx = m.denote ctx + n.denote ctx := by
simp only [add, denote, Int.add_mul, h]

theorem denote_mul {m₁ m₂ : Monomial} : (m₁.mul m₂).denote ctx = m₁.denote ctx * m₂.denote ctx := by
simp only [denote, mul, Int.mul_assoc]; congr 1
rw [← Int.mul_assoc, Int.mul_comm _ m₂.coeff, Int.mul_assoc]; congr 1
induction m₁.vars with
| nil => simp [Int.mul_assoc]
| cons y ys ih =>
simp [foldl_mul_insert, ←foldl_assoc Int.mul_assoc, ih]

end Monomial

Expand Down Expand Up @@ -111,20 +155,83 @@ def mul (p q : Polynomial) : Polynomial :=
def denote (ctx : Context) (p : Polynomial) : Int :=
p.foldl (fun acc m => acc + m.denote ctx) 0

theorem denote_neg {p : Polynomial} : p.neg.denote ctx = -p.denote ctx :=
sorry
theorem foldl_add_insert (ctx : Context) :
List.foldl (fun z a => z + (Monomial.denote ctx a)) 0 (add.insert m p) =
(Monomial.denote ctx m) + List.foldl (fun z a => z + (Monomial.denote ctx a)) 0 p := by
induction p with
| nil => simp [add.insert]
| cons n p ih =>
simp only [add.insert]
split <;> rename_i hlt <;> simp only [List.foldl_cons, Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc]
· split <;> rename_i heq
· split <;> rename_i hneq
· rw [←Int.add_assoc, Int.add_comm, ←Monomial.denote_add heq]
simp [Monomial.denote, hneq]
· simp [-Int.add_zero, Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc, Monomial.denote_add, heq, Int.add_assoc]
· simp only [List.foldl_cons, Int.add_comm 0, ih, Monomial.foldl_assoc Int.add_assoc]
rw [←Int.add_assoc, Int.add_comm (Monomial.denote ctx n), Int.add_assoc]

theorem denote_neg {p : Polynomial} : p.neg.denote ctx = -p.denote ctx := by
simp only [denote, neg]
induction p with
| nil => simp
| cons m p ih =>
simp only [List.foldl_cons, Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc,Int.neg_add, ←ih, List.map, Monomial.denote_neg]

theorem denote_add {p q : Polynomial} : (p.add q).denote ctx = p.denote ctx + q.denote ctx := by
simp only [denote, add]
induction p with
| nil => simp [add.insert]
| cons x ys ih =>
simp only [List.foldr_cons, List.foldl_cons, Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc, Int.add_assoc]
rw [← ih, foldl_add_insert]

theorem denote_add {p q : Polynomial} : (p.add q).denote ctx = p.denote ctx + q.denote ctx :=
sorry

theorem denote_sub {p q : Polynomial} : (p.sub q).denote ctx = p.denote ctx - q.denote ctx := by
simp only [sub, denote_neg, denote_add, Int.sub_eq_add_neg]

theorem denote_mulMonomial {p : Polynomial} : (p.mulMonomial m).denote ctx = m.denote ctx * p.denote ctx :=
sorry

theorem denote_mul {p q : Polynomial} : (p.mul q).denote ctx = p.denote ctx * q.denote ctx :=
sorry
theorem denote_mulMonomial {p : Polynomial} : (p.mulMonomial m).denote ctx = m.denote ctx * p.denote ctx := by
simp only [denote, mulMonomial, add]
induction p with
| nil => simp
| cons n p ih =>
simp only [List.foldl_cons, List.foldr_cons, Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc, Int.mul_add, ←ih]
simp [foldl_add_insert, Monomial.denote_mul]

theorem denote_cons {p : List Monomial} {ctx : Context} : denote ctx (m :: p) = m.denote ctx + denote ctx p := by
simp only [denote, List.foldl_cons, Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc]

theorem denote_nil_add : denote ctx (p.add []) = denote ctx p := by
induction p with
| nil => simp [add]
| cons n p ih =>
simp [denote_add, List.foldr_cons, denote_cons, ih, show denote ctx [] = 0 by rfl]

theorem denote_add_insert {g : Monomial → Polynomial} :
denote ctx (List.foldl (fun acc m => (g m).add acc) n p) = denote ctx n + denote ctx (List.foldl (fun acc m => (g m).add acc) [] p) := by
revert n
induction p with
| nil => simp [denote]
| cons k p ih =>
intro n
simp only [List.foldl_cons, List.foldr, @ih n]
rw [ih, @ih ((g k).add []), ← Int.add_assoc, denote_nil_add, denote_add, Int.add_comm _ (denote ctx n)]

theorem denote_foldl {g : Monomial → Polynomial} :
denote ctx (List.foldl (fun acc m => ((g m).add (acc))) [] p) = List.foldl (fun acc m => (g m).denote ctx + acc) 0 p := by
induction p with
| nil => simp [denote]
| cons n p ih =>
simp only [List.foldl_cons, Int.add_comm, List.foldr] at *
rw [Int.add_comm 0, Monomial.foldl_assoc Int.add_assoc, ←ih, denote_add_insert, denote_nil_add]

theorem denote_mul {p q : Polynomial} : (p.mul q).denote ctx = p.denote ctx * q.denote ctx := by
simp only [mul]
induction p with
| nil => simp [denote]
| cons n p ih =>
simp only [List.foldl_cons, denote_cons, Int.add_mul, ← ih]
rw [denote_foldl, denote_add_insert, ←denote_mulMonomial, denote_nil_add, denote_foldl]

end Polynomial

Expand Down