/-! # Tests exercising basic behaviour of `rw`. See also `tests/lean/rewrite.lean`. -/ -- Rewriting by `iff` example (h : P ↔ Q) (q : Q) : P := by rw [h] exact q example (h : P ↔ Q) (q : Q) : P := by rw [← h] at q exact q def f (_ : Nat) : Nat := 0 def g (n : Nat) : Nat := f n theorem t (n : Nat) : f n = f 0 := rfl theorem s (n m : Nat) : f n = f m := rfl example : f 1 = f 2 := by rw [s 1 2] -- closes the goal `f 2 = f 2` via `rfl` example : f 1 = f 2 := by rw [t] -- does not close the goal, because `rw` calls `rfl` under `withReducible` rfl example (h : f (f 1) = 0) : f (g 1) = 0 := by fail_if_success rw [h] -- Can not see through definition of `g` erw [h] -- "Expensive" rewrite can -- Check `(config := ...)` works: example (h : f (f 1) = 0) : f (g 1) = 0 := by rw (config := {transparency := .default}) [h] -- This is just `erw`. attribute [reducible] f example : f 1 = f 2 := by rw [] -- Empty rewrite closes the goal via `rfl` example : f 1 = f 2 := by rw [t] -- Closes the goal via `rfl` example : f 1 = f 2 := by rw [s 1 3, s 3 4] -- Closes the goal via `rfl` set_option allowUnsafeReducibility true -- For the remaining tests we prevent `rfl` from closing the goal. attribute [irreducible] f -- Multiple rewrites example : f 3 = f 7 := by rw [s 3 5, s 5 7] -- Rewrite only modifies the main goal. example (h : f 2 = f 3) : f 1 = f 2 := by rw [s 2 3, s 1 2] assumption -- Rewrite `at` example (h : f 2 = f 3) : f 1 = f 2 := by rw [s 2 1] at h rw [s 2 3] assumption -- Rewriting only affects the first occurrence. -- Providing an argument allows rewriting other occurrences. example : [f 1, f 2] = [f 0, f 0] := by rw [t] rw [t] rw [t 2] -- We can rewrite backwards. example : f 1 = f 0 := by rw [← t 2] rw [t] rw [t 2] -- Rewriting simultaneously replaces all occurrences of the first match. example : [f 1, f 2, f 1] = [f 0, f 0, f 0] := by rw [t] rw [t 2] -- Rewriting by lemmas with undetermined arguments creates additional goals. example : f 2 = f 3 := by rewrite [s] rfl -- These are often solved by the implicit `rfl` at the end of `rw`. example : f 2 = f 3 := by rw [s] -- We can rewrite at multiple locations, -- specializing the arguments differently at each location. -- This behaviour was accidentally broken by -- https://github.com/leanprover/lean4/pull/2317 -- and required a revert. example (w₁ : f 1 = 0) (w₂ : f 2 = 0) : f 3 = 0 ∧ f 0 = 0 := by rw [t] at w₁ w₂ ⊢ exact ⟨w₁, w₂⟩ class P (n : Nat) theorem t' (n : Nat) [P n] : f n = f 0 := t n -- Rewriting uses typeclass synthesis to fill arguments. example [∀ n, P n] : f 2 = f 0 := by rw [t'] example : f 2 = f 0 := by fail_if_success rw [t'] -- failed to synthesize P 2 fail_if_success rw [@t' 2 _] -- failed to synthesize P 2 -- By putting placeholders in a typeclass argument -- we can return the problem to the user. rw [@t' 2 ?_] constructor