Ir al contenido principal

La semana en Calculemus (11 de mayo de 2024)

Esta semana he publicado en Calculemus las demostraciones con Lean4 de las siguientes propiedades:

A continuación se muestran las soluciones.

1. Producto de potencias de la misma base en monoides

En los monoides se define la potencia con exponentes naturales. En Lean la potencia x^n se se caracteriza por los siguientes lemas:

   pow_zero : x^0 = 1
   pow_succ : x^(succ n) = x * x^n

Demostrar con Lean4 que si \(M\) es un monoide, \(x ∈ M\) y \(m, n ∈ ℕ\), entonces \[ x^{m + n} = x^m x^n \]

Para ello, completar la siguiente teoría de Lean4:

import Mathlib.Algebra.Group.Defs
import Mathlib.Algebra.GroupPower.Basic
open Nat

variable {M : Type} [Monoid M]
variable (x : M)
variable (m n : )

example :
  x^(m + n) = x^m * x^n :=
by sorry

1.1. Demostración en lenguaje natural

Por inducción en \(m\).

Base: \begin{align} x^{0 + n} &= x^n \newline &= 1 · x^n \newline &= x^0 · x^n &&\text{[por pow_zero]} \end{align}

Paso: Supongamos que \[ x^{m + n} = x^m x^n \tag{HI} \] Entonces \begin{align} x^{(m+1) + n} &= x^{(m + n) + 1} \newline &= x · x^{m + n} &&\text{[por pow_succ]} \newline &= x · (x^m · x^n) &&\text{[por HI]} \newline &= (x · x^m) · x^n \newline &= x^{m+1} · x^n &&\text{[por pow_succ]} \end{align}

1.2. Demostraciones con Lean4

import Mathlib.Algebra.Group.Defs
import Mathlib.Algebra.GroupPower.Basic
open Nat

variable {M : Type} [Monoid M]
variable (x : M)
variable (m n : )

-- 1ª demostración
-- ===============

example :
  x^(m + n) = x^m * x^n :=
by
  induction' m with m HI
  . calc x^(0 + n)
       = x^n               := congrArg (x ^ .) (Nat.zero_add n)
     _ = 1 * x^n           := (Monoid.one_mul (x^n)).symm
     _ = x^0 * x^n         := congrArg (. * (x^n)) (pow_zero x).symm
  . calc x^(succ m + n)
       = x^succ (m + n)    := congrArg (x ^.) (succ_add m n)
     _ = x * x^(m + n)     := pow_succ x (m + n)
     _ = x * (x^m * x^n)   := congrArg (x * .) HI
     _ = (x * x^m) * x^n   := (mul_assoc x (x^m) (x^n)).symm
     _ = x^succ m * x^n    := congrArg (. * x^n) (pow_succ x m).symm

-- 2ª demostración
-- ===============

example :
  x^(m + n) = x^m * x^n :=
by
  induction' m with m HI
  . calc x^(0 + n)
       = x^n             := by simp only [Nat.zero_add]
     _ = 1 * x^n         := by simp only [Monoid.one_mul]
     _ = x^0 * x^n       := by simp only [_root_.pow_zero]
  . calc x^(succ m + n)
       = x^succ (m + n)  := by simp only [succ_add]
     _ = x * x^(m + n)   := by simp only [_root_.pow_succ]
     _ = x * (x^m * x^n) := by simp only [HI]
     _ = (x * x^m) * x^n := (mul_assoc x (x^m) (x^n)).symm
     _ = x^succ m * x^n  := by simp only [_root_.pow_succ]

-- 3ª demostración
-- ===============

example :
  x^(m + n) = x^m * x^n :=
by
  induction' m with m HI
  . calc x^(0 + n)
       = x^n             := by simp [Nat.zero_add]
     _ = 1 * x^n         := by simp
     _ = x^0 * x^n       := by simp
  . calc x^(succ m + n)
       = x^succ (m + n)  := by simp [succ_add]
     _ = x * x^(m + n)   := by simp [_root_.pow_succ]
     _ = x * (x^m * x^n) := by simp [HI]
     _ = (x * x^m) * x^n := (mul_assoc x (x^m) (x^n)).symm
     _ = x^succ m * x^n  := by simp [_root_.pow_succ]

-- 4ª demostración
-- ===============

example :
  x^(m + n) = x^m * x^n :=
pow_add x m n

-- Lemas usados
-- ============

-- variable (y z : M)
-- #check (Monoid.one_mul x : 1 * x = x)
-- #check (Nat.zero_add n : 0 + n = n)
-- #check (mul_assoc x y z : (x * y) * z = x * (y * z))
-- #check (pow_add x m n : x^(m + n) = x^m * x^n)
-- #check (pow_succ x n : x ^ succ n = x * x ^ n)
-- #check (pow_zero x : x ^ 0 = 1)
-- #check (succ_add n m : succ n + m = succ (n + m))

Se puede interactuar con las demostraciones anteriores en Lean 4 Web.

1.3. Demostraciones con Isabelle/HOL

theory Producto_de_potencias_de_la_misma_base_en_monoides
imports Main
begin

context monoid_mult
begin

(* 1ª demostración *)

lemma "x ^ (m + n) = x ^ m * x ^ n"
proof (induct m)
  have "x ^ (0 + n) = x ^ n"                by (simp only: add_0)
  also have "… = 1 * x ^ n"                 by (simp only: mult_1_left)
  also have "… = x ^ 0 * x ^ n"             by (simp only: power_0)
  finally show "x ^ (0 + n) = x ^ 0 * x ^ n"
    by this
next
  fix m
  assume HI : "x ^ (m + n) = x ^ m * x ^ n"
  have "x ^ (Suc m + n) = x ^ Suc (m + n)"   by (simp only: add_Suc)
  also have "… = x *  x ^ (m + n)"           by (simp only: power_Suc)
  also have "… = x *  (x ^ m * x ^ n)"       by (simp only: HI)
  also have "… = (x *  x ^ m) * x ^ n"       by (simp only: mult_assoc)
  also have "… = x ^ Suc m * x ^ n"          by (simp only: power_Suc)
  finally show "x ^ (Suc m + n) = x ^ Suc m * x ^ n"
    by this
qed

(* 2ª demostración *)

lemma "x ^ (m + n) = x ^ m * x ^ n"
proof (induct m)
  have "x ^ (0 + n) = x ^ n"                 by simp
  also have "… = 1 * x ^ n"                  by simp
  also have "… = x ^ 0 * x ^ n"              by simp
  finally show "x ^ (0 + n) = x ^ 0 * x ^ n"
    by this
next
  fix m
  assume HI : "x ^ (m + n) = x ^ m * x ^ n"
  have "x ^ (Suc m + n) = x ^ Suc (m + n)"   by simp
  also have "… = x *  x ^ (m + n)"           by simp
  also have "… = x *  (x ^ m * x ^ n)"       using HI by simp
  also have "… = (x *  x ^ m) * x ^ n"       by (simp add: mult_assoc)
  also have "… = x ^ Suc m * x ^ n"          by simp
  finally show "x ^ (Suc m + n) = x ^ Suc m * x ^ n"
    by this
qed

(* 3ª demostración *)

lemma "x ^ (m + n) = x ^ m * x ^ n"
proof (induct m)
  case 0
  then show ?case
    by simp
next
  case (Suc m)
  then show ?case
    by (simp add: algebra_simps)
qed

(* 4ª demostración *)

lemma "x ^ (m + n) = x ^ m * x ^ n"
  by (induct m) (simp_all add: algebra_simps)

(* 5ª demostración *)

lemma "x ^ (m + n) = x ^ m * x ^ n"
  by (simp only: power_add)

end

end

2. Equivalencia de inversos iguales al neutro

Sea \(M\) un monoide y \(a, b ∈ M\) tales que \(ab = 1\). Demostrar con Lean4 que \(a = 1\) si y sólo si \(b = 1\).

Para ello, completar la siguiente teoría de Lean4:

import Mathlib.Algebra.Group.Basic

variable {M : Type} [Monoid M]
variable {a b : M}

example
  (h : a * b = 1)
  : a = 1  b = 1 :=
by sorry

2.1. Demostración en lenguaje natural

Demostraremos las dos implicaciones.

(⟹) Supongamos que \(a = 1\). Entonces, \begin{align} b &= 1·b &&\text{[por neutro por la izquierda]} \newline &= a·b &&\text{[por supuesto]} \newline &= 1 &&\text{[por hipótesis]} \end{align}

(⟸) Supongamos que \(b = 1\). Entonces, \begin{align} a &= a·1 &&\text{[por neutro por la derecha]} \newline &= a·b &&\text{[por supuesto]} \newline &= 1 &&\text{[por hipótesis]} \end{align}

2.2. Demostraciones con Lean4

import Mathlib.Algebra.Group.Basic

variable {M : Type} [Monoid M]
variable {a b : M}

-- 1ª demostración
-- ===============

example
  (h : a * b = 1)
  : a = 1  b = 1 :=
by
  constructor
  . -- ⊢ a = 1 → b = 1
    intro a1
    -- a1 : a = 1
    -- ⊢ b = 1
    calc b = 1 * b := (one_mul b).symm
         _ = a * b := congrArg (. * b) a1.symm
         _ = 1     := h
  . -- ⊢ b = 1 → a = 1
    intro b1
    -- b1 : b = 1
    -- ⊢ a = 1
    calc a = a * 1 := (mul_one a).symm
         _ = a * b := congrArg (a * .) b1.symm
         _ = 1     := h

-- 2ª demostración
-- ===============

example
  (h : a * b = 1)
  : a = 1  b = 1 :=
by
  constructor
  . -- ⊢ a = 1 → b = 1
    intro a1
    -- a1 : a = 1
    -- ⊢ b = 1
    rw [a1] at h
    -- h : 1 * b = 1
    rw [one_mul] at h
    -- h : b = 1
    exact h
  . -- ⊢ b = 1 → a = 1
    intro b1
    -- b1 : b = 1
    -- ⊢ a = 1
    rw [b1] at h
    -- h : a * 1 = 1
    rw [mul_one] at h
    -- h : a = 1
    exact h

-- 3ª demostración
-- ===============

example
  (h : a * b = 1)
  : a = 1  b = 1 :=
by
  constructor
  . -- ⊢ a = 1 → b = 1
    rintro rfl
    -- h : 1 * b = 1
    simpa using h
  . -- ⊢ b = 1 → a = 1
    rintro rfl
    -- h : a * 1 = 1
    simpa using h

-- 4ª demostración
-- ===============

example
  (h : a * b = 1)
  : a = 1  b = 1 :=
by constructor <;> (rintro rfl; simpa using h)

-- 5ª demostración
-- ===============

example
  (h : a * b = 1)
  : a = 1  b = 1 :=
eq_one_iff_eq_one_of_mul_eq_one h

-- Lemas usados
-- ============

-- #check (eq_one_iff_eq_one_of_mul_eq_one : a * b = 1 → (a = 1 ↔ b = 1))
-- #check (mul_one a : a * 1 = a)
-- #check (one_mul a : 1 * a = a)

Se puede interactuar con las demostraciones anteriores en Lean 4 Web.

2.3. Demostraciones con Isabelle/HOL

theory Equivalencia_de_inversos_iguales_al_neutro
imports Main
begin

context monoid
begin

(* 1ª demostración *)

lemma
  assumes "a * b = 1"
  shows   "a = 1 ⟷ b = 1"
proof (rule iffI)
  assume "a = 1"
  have "b = 1 * b"      by (simp only: left_neutral)
  also have "… = a * b" by (simp only: ‹a = 1›)
  also have "… = 1"     by (simp only: ‹a * b = 1›)
  finally show "b = 1"  by this
next
  assume "b = 1"
  have "a = a * 1"      by (simp only: right_neutral)
  also have "… = a * b" by (simp only: ‹b = 1›)
  also have "… = 1"     by (simp only: ‹a * b = 1›)
  finally show "a = 1"  by this
qed

(* 2ª demostración *)

lemma
  assumes "a * b = 1"
  shows   "a = 1 ⟷ b = 1"
proof
  assume "a = 1"
  have "b = 1 * b"      by simp
  also have "… = a * b" using ‹a = 1› by simp
  also have "… = 1"     using ‹a * b = 1› by simp
  finally show "b = 1"  .
next
  assume "b = 1"
  have "a = a * 1"      by simp
  also have "… = a * b" using ‹b = 1› by simp
  also have "… = 1"     using ‹a * b = 1› by simp
  finally show "a = 1"  .
qed

(* 3ª demostración *)

lemma
  assumes "a * b = 1"
  shows   "a = 1 ⟷ b = 1"
  by (metis assms left_neutral right_neutral)

end

end

3. Unicidad de inversos en monoides

Demostrar con Lean4 que si \(M\) es un monoide conmutativo y \(x, y, z ∈ M\) tales que \(x·y = 1\) y \(x·z = 1\), entonces \(y = z\).

Para ello, completar la siguiente teoría de Lean4:

import Mathlib.Algebra.Group.Basic

variable {M : Type} [CommMonoid M]
variable {x y z : M}

example
  (hy : x * y = 1)
  (hz : x * z = 1)
  : y = z :=
by sorry

3.1. Demostración en lenguaje natural

Por la siguiente cadena de igualdades \begin{align} y &= 1·y &&\text{[por neutro a la izquierda]} \newline &= (x·z)·y &&\text{[por hipótesis]} \newline &= (z·x)·y &&\text{[por la conmutativa]} \newline &= z·(x·y) &&\text{[por la asociativa]} \newline &= z·1 &&\text{[por hipótesis]} \newline &= z &&\text{[por neutro a la derecha]} \end{align}

3.2. Demostraciones con Lean4

import Mathlib.Algebra.Group.Basic

variable {M : Type} [CommMonoid M]
variable {x y z : M}

-- 1ª demostración
-- ===============

example
  (hy : x * y = 1)
  (hz : x * z = 1)
  : y = z :=
calc y = 1 * y       := (one_mul y).symm
     _ = (x * z) * y := congrArg (. * y) hz.symm
     _ = (z * x) * y := congrArg (. * y) (mul_comm x z)
     _ = z * (x * y) := mul_assoc z x y
     _ = z * 1       := congrArg (z * .) hy
     _ = z           := mul_one z

-- 2ª demostración
-- ===============

example
  (hy : x * y = 1)
  (hz : x * z = 1)
  : y = z :=
calc y = 1 * y     := by simp only [one_mul]
   _ = (x * z) * y := by simp only [hz]
   _ = (z * x) * y := by simp only [mul_comm]
   _ = z * (x * y) := by simp only [mul_assoc]
   _ = z * 1       := by simp only [hy]
   _ = z           := by simp only [mul_one]

-- 3ª demostración
-- ===============

example
  (hy : x * y = 1)
  (hz : x * z = 1)
  : y = z :=
calc y = 1 * y     := by simp
   _ = (x * z) * y := by simp [hz]
   _ = (z * x) * y := by simp [mul_comm]
   _ = z * (x * y) := by simp [mul_assoc]
   _ = z * 1       := by simp [hy]
   _ = z           := by simp

-- 4ª demostración
-- ===============

example
  (hy : x * y = 1)
  (hz : x * z = 1)
  : y = z :=
by
  apply left_inv_eq_right_inv _ hz
  -- ⊢ y * x = 1
  rw [mul_comm]
  -- ⊢ x * y = 1
  exact hy

-- 5ª demostración
-- ===============

example
  (hy : x * y = 1)
  (hz : x * z = 1)
  : y = z :=
inv_unique hy hz

-- Lemas usados
-- ============

-- #check (inv_unique : x * y = 1 → x * z = 1 → y = z)
-- #check (left_inv_eq_right_inv : y * x = 1 → x * z = 1 → y = z)
-- #check (mul_assoc x y z : (x * y) * z = x * (y * z))
-- #check (mul_comm x y : x * y = y * x)
-- #check (mul_one x : x * 1 = x)
-- #check (one_mul x : 1 * x = x)

Se puede interactuar con las demostraciones anteriores en Lean 4 Web.

3.3. Demostraciones con Isabelle/HOL

theory Unicidad_de_inversos_en_monoides
imports Main
begin

context comm_monoid
begin

(* 1ª demostración *)

lemma
  assumes "x * y = 1"
          "x * z = 1"
  shows "y = z"
proof -
  have "y = 1 * y"            by (simp only: left_neutral)
  also have "… = (x * z) * y" by (simp only: ‹x * z = 1›)
  also have "… = (z * x) * y" by (simp only: commute)
  also have "… = z * (x * y)" by (simp only: assoc)
  also have "… = z * 1"       by (simp only: ‹x * y = 1›)
  also have "… = z"           by (simp only: right_neutral)
  finally show "y = z"        by this
qed

(* 2ª demostración *)

lemma
  assumes "x * y = 1"
          "x * z = 1"
  shows "y = z"
proof -
  have "y = 1 * y"            by simp
  also have "… = (x * z) * y" using assms(2) by simp
  also have "… = (z * x) * y" by simp
  also have "… = z * (x * y)" by simp
  also have "… = z * 1"       using assms(1) by simp
  also have "… = z"           by simp
  finally show "y = z"        by this
qed

(* 3ª demostración *)

lemma
  assumes "x * y = 1"
          "x * z = 1"
  shows "y = z"
  using assms
  by auto

end

end

4. Caracterización de producto igual al primer factor

Un monoide cancelativo por la izquierda es un monoide \(M\) que cumple la propiedad cancelativa por la izquierda; es decir, para todo \(a, b ∈ M\) \[ a·b = a·c ↔ b = c \]

En Lean4 la clase de los monoides cancelativos por la izquierda es LeftCancelMonoid y la propiedad cancelativa por la izquierda es

   mul_left_cancel : a * b = a * c  b = c

Demostrar con Lean4 que si \(M\) es un monoide cancelativo por la izquierda y \(a, b ∈ M\), entonces \[ a·b = a ↔ b = 1 \]

Para ello, completar la siguiente teoría de Lean4:

import Mathlib.Algebra.Group.Basic

variable {M : Type} [LeftCancelMonoid M]
variable {a b : M}

example : a * b = a  b = 1 :=
by sorry

4.1. Demostración en lenguaje natural

Demostraremos las dos implicaciones.

(⟹) Supongamos que \[ a·b = a \] Por la propiedad del neutro por la derecha tenemos \[ a·1 = a \] Por tanto, \[ a·b = a·1 \] y, por la propiedad cancelativa, \[ b = 1 \]

(⟸) Supongamos que \(b = 1\). Entonces, \begin{align} a·b &= a·1 \newline &= a &&\text{[por el neutro por la derecha]} \end{align}

4.2. Demostraciones con Lean4

import Mathlib.Algebra.Group.Basic

variable {M : Type} [LeftCancelMonoid M]
variable {a b : M}

-- 1ª demostración
-- ===============

example : a * b = a  b = 1 :=
by
  constructor
  . -- ⊢ a * b = a → b = 1
    intro h
    -- h : a * b = a
    -- ⊢ b = 1
    have h1 : a * b = a * 1 := by
      calc a * b = a     := by exact h
               _ = a * 1 := (mul_one a).symm
    exact mul_left_cancel h1
  . -- ⊢ b = 1 → a * b = a
    intro h
    -- h : b = 1
    -- ⊢ a * b = a
    rw [h]
    -- ⊢ a * 1 = a
    exact mul_one a

-- 2ª demostración
-- ===============

example : a * b = a  b = 1 :=
calc a * b = a
      a * b = a * 1 := by rw [mul_one]
   _  b = 1         := mul_left_cancel_iff

-- 3ª demostración
-- ===============

example : a * b = a  b = 1 :=
mul_right_eq_self

-- 4ª demostración
-- ===============

example : a * b = a  b = 1 :=
by aesop

-- Lemas usados
-- ============

-- variable (c : M)
-- #check (mul_left_cancel : a * b = a * c → b = c)
-- #check (mul_one a : a * 1 = a)
-- #check (mul_right_eq_self : a * b = a ↔ b = 1)

Se puede interactuar con las demostraciones anteriores en Lean 4 Web.

4.3. Demostraciones con Isabelle/HOL

theory Caracterizacion_de_producto_igual_al_primer_factor
imports Main
begin

context cancel_comm_monoid_add
begin

(* 1ª demostración *)

lemma "a + b = a ⟷ b = 0"
proof (rule iffI)
  assume "a + b = a"
  then have "a + b = a + 0"     by (simp only: add_0_right)
  then show "b = 0"             by (simp only: add_left_cancel)
next
  assume "b = 0"
  have "a + 0 = a"              by (simp only: add_0_right)
  with ‹b = 0› show "a + b = a" by (rule ssubst)
qed

(* 2ª demostración *)

lemma "a + b = a ⟷ b = 0"
proof
  assume "a + b = a"
  then have "a + b = a + 0" by simp
  then show "b = 0"         by simp
next
  assume "b = 0"
  have "a + 0 = a"          by simp
  then show "a + b = a"     using ‹b = 0› by simp
qed

(* 3ª demostración *)

lemma "a + b = a ⟷ b = 0"
proof -
  have "(a + b = a) ⟷ (a + b = a + 0)" by (simp only: add_0_right)
  also have "… ⟷ (b = 0)"              by (simp only: add_left_cancel)
  finally show "a + b = a ⟷ b = 0"     by this
qed

(* 4ª demostración *)

lemma "a + b = a ⟷ b = 0"
proof -
  have "(a + b = a) ⟷ (a + b = a + 0)" by simp
  also have "… ⟷ (b = 0)"              by simp
  finally show "a + b = a ⟷ b = 0"     .
qed

(* 5ª demostración *)

lemma "a + b = a ⟷ b = 0"
  by (simp only: add_cancel_left_right)

(* 6ª demostración *)

lemma "a + b = a ⟷ b = 0"
  by auto

end

end

5. Unicidad del elemento neutro en los grupos

Demostrar con Lean4 que un grupo sólo posee un elemento neutro.

Para ello, completar la siguiente teoría de Lean4:

import Mathlib.Algebra.Group.Basic

variable {G : Type} [Group G]

example
  (e : G)
  (h :  x, x * e = x)
  : e = 1 :=
sorry

5.1. Demostración en lenguaje natural

Sea \(e ∈ G\) tal que \[ (∀ x)[x·e = x] \tag{1} \] Entonces, \begin{align} e &= 1.e &&\text{[porque 1 es neutro]} \newline &= 1 &&\text{[por (1)]} \end{align}

5.2. Demostraciones con Lean4

import Mathlib.Algebra.Group.Basic

variable {G : Type} [Group G]

-- 1ª demostración
-- ===============

example
  (e : G)
  (h :  x, x * e = x)
  : e = 1 :=
calc e = 1 * e := (one_mul e).symm
     _ = 1     := h 1

-- 2ª demostración
-- ===============

example
  (e : G)
  (h :  x, x * e = x)
  : e = 1 :=
by
  have h1 : e = e * e := (h e).symm
  exact self_eq_mul_left.mp h1

-- 3ª demostración
-- ===============

example
  (e : G)
  (h :  x, x * e = x)
  : e = 1 :=
self_eq_mul_left.mp (h e).symm

-- 4ª demostración
-- ===============

example
  (e : G)
  (h :  x, x * e = x)
  : e = 1 :=
by aesop

-- Lemas usados
-- ============

-- variable (a b : G)
-- #check (one_mul a : 1 * a = a)
-- #check (self_eq_mul_left : b = a * b ↔ a = 1)

Se puede interactuar con las demostraciones anteriores en Lean 4 Web.

5.3. Demostraciones con Isabelle/HOL

theory Unicidad_del_elemento_neutro_en_los_grupos
imports Main
begin

context group
begin

(* 1ª demostración *)

lemma
  assumes "∀ x. x * e = x"
  shows   "e = 1"
proof -
  have "e = 1 * e"     by (simp only: left_neutral)
  also have "… = 1"    using assms by (rule allE)
  finally show "e = 1" by this
qed

(* 2ª demostración *)

lemma
  assumes "∀ x. x * e = x"
  shows   "e = 1"
proof -
  have "e = 1 * e"     by simp
  also have "… = 1"    using assms by simp
  finally show "e = 1" .
qed

(* 3ª demostración *)

lemma
  assumes "∀ x. x * e = x"
  shows   "e = 1"
  using assms
  by (metis left_neutral)

end

end