/- Copyright (c) 2023 Lean FRO. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joe Hendrix -/ module prelude import Init.Data.Bool import Init.Data.Nat.Basic import Init.Data.Nat.Lemmas /-! This contains lemmas used by the Nat simprocs for simplifying arithmetic addition offsets. -/ namespace Nat.Simproc /- Sub proofs -/ theorem sub_add_eq_comm (a b c : Nat) : a - (b + c) = a - c - b := by rw [Nat.add_comm b c] exact Nat.sub_add_eq a c b theorem add_sub_add_le (a c : Nat) {b d : Nat} (h : b ≤ d) : a + b - (c + d) = a - (c + (d-b)) := by induction b generalizing a c d with | zero => simp | succ b ind => match d with | 0 => contradiction | d + 1 => have g := Nat.le_of_succ_le_succ h rw [Nat.add_succ a, Nat.add_succ c, Nat.succ_sub_succ, Nat.succ_sub_succ, ind _ _ g] theorem add_sub_add_ge (a c : Nat) {b d : Nat} (h : b ≥ d) : a + b - (c + d) = a + (b - d) - c := by rw [Nat.add_comm c d, Nat.sub_add_eq, Nat.add_sub_assoc h a] theorem add_sub_le (a : Nat) {b c : Nat} (h : b ≤ c) : a + b - c = a - (c - b) := by have p := add_sub_add_le a 0 h simp only [Nat.zero_add] at p exact p /- Eq proofs -/ theorem add_eq_gt (a : Nat) {b c : Nat} (h : b > c) : (a + b = c) = False := eq_false (Nat.ne_of_gt (Nat.lt_of_lt_of_le h (le_add_left b a))) theorem eq_add_gt (a : Nat) {b c : Nat} (h : c > a) : (a = b + c) = False := by rw [@Eq.comm Nat a (b + c)] exact add_eq_gt b h theorem add_eq_add_le (a c : Nat) {b d : Nat} (h : b ≤ d) : (a + b = c + d) = (a = c + (d - b)) := by have g : b ≤ c + d := Nat.le_trans h (le_add_left d c) rw [← Nat.add_sub_assoc h, @Eq.comm _ a, Nat.sub_eq_iff_eq_add g, @Eq.comm _ (a + b)] theorem add_eq_add_ge (a c : Nat) {b d : Nat} (h : b ≥ d) : (a + b = c + d) = (a + (b - d) = c) := by rw [@Eq.comm _ (a + b) _, add_eq_add_le c a h, @Eq.comm _ _ c] theorem add_eq_le (a : Nat) {b c : Nat} (h : b ≤ c) : (a + b = c) = (a = c - b) := by have r := add_eq_add_le a 0 h simp only [Nat.zero_add] at r exact r theorem eq_add_le {a : Nat} (b : Nat) {c : Nat} (h : c ≤ a) : (a = b + c) = (b = a - c) := by rw [@Eq.comm Nat a (b + c)] exact add_eq_le b h /- Lemmas for lifting Eq proofs to beq -/ theorem beqEqOfEqEq {a b c d : Nat} (p : (a = b) = (c = d)) : (a == b) = (c == d) := by simp only [Bool.beq_eq_decide_eq, p] theorem beqFalseOfEqFalse {a b : Nat} (p : (a = b) = False) : (a == b) = false := by simp [Bool.beq_eq_decide_eq, p] theorem bneEqOfEqEq {a b c d : Nat} (p : (a = b) = (c = d)) : (a != b) = (c != d) := by simp only [bne, beqEqOfEqEq p] theorem bneTrueOfEqFalse {a b : Nat} (p : (a = b) = False) : (a != b) = true := by simp [bne, beqFalseOfEqFalse p] /- le proofs -/ theorem add_le_add_le (a c : Nat) {b d : Nat} (h : b ≤ d) : (a + b ≤ c + d) = (a ≤ c + (d - b)) := by rw [← Nat.add_sub_assoc h, Nat.le_sub_iff_add_le] exact Nat.le_trans h (le_add_left d c) theorem add_le_add_ge (a c : Nat) {b d : Nat} (h : b ≥ d) : (a + b ≤ c + d) = (a + (b - d) ≤ c) := by rw [← Nat.add_sub_assoc h, Nat.sub_le_iff_le_add] theorem add_le_le (a : Nat) {b c : Nat} (h : b ≤ c) : (a + b ≤ c) = (a ≤ c - b) := by have r := add_le_add_le a 0 h simp only [Nat.zero_add] at r exact r theorem add_le_gt (a : Nat) {b c : Nat} (h : b > c) : (a + b ≤ c) = False := eq_false (Nat.not_le_of_gt (Nat.lt_of_lt_of_le h (le_add_left b a))) theorem le_add_le (a : Nat) {b c : Nat} (h : a ≤ c) : (a ≤ b + c) = True := eq_true (Nat.le_trans h (le_add_left c b)) theorem le_add_ge (a : Nat) {b c : Nat} (h : a ≥ c) : (a ≤ b + c) = (a - c ≤ b) := by have r := add_le_add_ge 0 b h simp only [Nat.zero_add] at r exact r end Nat.Simproc