Lógica y demostración con Lean

Índice

Resumen del curso Logic and proof. Su código está aquí.

Hay en local una copia del libro y del código.

1 Introducción

  • Crear el proyecto

    cd ~/alonso/estudio
    leanproject new Logica_y_demostracion_con_Lean
    
  • El resultado es

    estudio> leanproject new Logica_y_demostracion_con_Lean
    > cd Logica_y_demostracion_con_Lean
    > git init -q
    > git checkout -b lean-3.15.0
    Cambiado a nueva rama 'lean-3.15.0'
    configuring Logica_y_demostracion_con_Lean 0.1
    Adding mathlib
    mathlib: cloning https://github.com/leanprover-community/mathlib to _target/deps/mathlib
    > git clone https://github.com/leanprover-community/mathlib _target/deps/mathlib
    Clonando en '_target/deps/mathlib'...
    remote: Enumerating objects: 43, done.        
    remote: Counting objects: 100% (43/43), done.        
    remote: Compressing objects: 100% (39/39), done.        
    remote: Total 51801 (delta 17), reused 12 (delta 4), pack-reused 51758        
    Recibiendo objetos: 100% (51801/51801), 22.33 MiB | 14.55 MiB/s, listo.
    Resolviendo deltas: 100% (40019/40019), listo.
    > git checkout --detach d9934b2681b12b9b5558b6913f80c037e1be7a9a    # in directory _target/deps/mathlib
    HEAD está ahora en d9934b26 feat(linear_algebra/basic): curry is linear_equiv (#3012)
    configuring Logica_y_demostracion_con_Lean 0.1
    mathlib: trying to update _target/deps/mathlib to revision d9934b2681b12b9b5558b6913f80c037e1be7a9a
    > git checkout --detach d9934b2681b12b9b5558b6913f80c037e1be7a9a    # in directory _target/deps/mathlib
    HEAD está ahora en d9934b26 feat(linear_algebra/basic): curry is linear_equiv (#3012)
    Looking for local mathlib oleans
    Found local mathlib oleans
    

2 Lógica proposicional en Lean

2.1 Expresiones para proposiciones y demostraciones

variables A B C : Prop

#check A  ¬ B  C 
-- Da 
--    A ∧ ¬B → C : Prop

#+INLCLUDE "./src/Cap_4/Declaracion_hipotesis.lean" src lean

variables A B : Prop
variable h : A  ¬ B

#check and.left h   
-- Da
--    h.left : A

#check and.right h  
-- Da
--    h.right : ¬B
variables A B : Prop
variable h : A  ¬B

#check and.intro (and.right h) (and.left h)  
-- Da 
--    ⟨h.right, h.left⟩ : ¬B ∧ A
variables A B C D : Prop

variable h1 : A  (B  C)
variable h2 : D  A
variable h3 : D
variable h4 : B

#check h2 h3            
-- | h2 h3 : A

#check h1 (h2 h3)       
-- | h1 (h2 h3): B → C

#check (h1 (h2 h3)) h4  
-- | (h1 (h2 h3)) h4 : C
variable A : Prop

#check (assume h : A, and.intro h h) 
-- | λ (h : A), ⟨h, h⟩ : A → A ∧ A 

2.2 Más órdenes

2.2.1 La orden example

variables A B : Prop

example : A  ¬B  ¬B  A :=
  assume h : A  ¬B,
  and.intro (and.right h) (and.left h)
variables A B : Prop

example : A  ¬B  ¬B  A :=
  assume h,
  and.intro (and.right h) (and.left h)

2.2.2 La orden show

variables A B : Prop

example : A  ¬B  ¬B  A :=
  assume h : A  ¬B,
  show ¬B  A, from and.intro (and.right h) (and.left h)
variables A B : Prop

example : A  ¬B  ¬B  A :=
assume h : A  ¬B,
show ¬B  A, from and.intro
  (show ¬B, from and.right h)
  (show A,  from and.left h)

2.2.3 Declaraciones en los argumentos

example (A B : Prop) : A  ¬B  ¬B  A :=
  assume h : A  ¬B,
  show ¬B  A, from and.intro (and.right h) (and.left h)

2.2.4 La orden sorry

variables A B : Prop

example : A  ¬ B  ¬ B  A :=
  assume h, sorry

example : A  ¬ B  ¬ B  A :=
  assume h, and.intro sorry sorry

example : A  ¬ B  ¬ B  A :=
  assume h, and.intro (and.right h) sorry

example : A  ¬ B  ¬ B  A :=
  assume h, and.intro (and.right h) (and.left h)

2.2.5 El uso de huecos

variables A B : Prop

example : A  ¬ B  ¬ B  A :=
  assume h, and.intro _ _

example : A  ¬ B  ¬ B  A :=
  assume h, and.intro (and.right h) (and.left h)

2.2.6 Secciones

2.3 Construcción de demostraciones por deducción natural

2.3.1 Implicación

variables A B : Prop

example : A  B :=
  assume h : A,
  show B, from sorry

section
  variable h1 : A  B
  variable h2 : A

  example : B := h1 h2
end

2.3.2 Conjunción

variables A B : Prop

section
  variables (h1 : A) (h2 : B)

  example : A  B := and.intro h1 h2
end

section
  variable h : A  B

  example : A := and.left h
  example : B := and.right h
end

2.4 Disyunción

variables A B : Prop

section
  variable h : A

  example : A  B := or.inl h
end

section
  variable h : B

  example : A  B := or.inr h
end
variables A B C : Prop

section
  variable h : A  B
  variables (ha : A  C) (hb : B  C)

  example : C :=
  or.elim h
    (assume h1 : A,
      show C, from ha h1)
    (assume h2 : B,
      show C, from hb h2)
end

2.4.1 Negación

variable A : Prop

section
  example : ¬A :=
    assume h : A,
    show false, from sorry
end
variable A : Prop

-- BEGIN
section
  variable h1 : ¬A
  variable h2 : A

  example : false := h1 h2
end

2.4.2 Verdad y falsedad

variables A : Prop

-- BEGIN
section
  variable h : false

  example : A := false.elim h
end
example : true := trivial

2.4.3 Bicondicional

variables A B : Prop

example : A  B :=
  iff.intro
    (assume h : A,
      show B, from sorry)
    (assume h : B,
      show A, from sorry)
variables A B : Prop

section
  variable h1 : A  B
  variable h2 : A

  example : B := iff.elim_left h1 h2
end

section
  variable h1 : A  B
  variable h2 : B

  example : A := iff.elim_right h1 h2
end

2.4.4 Reducción al absurdo

variables A : Prop

section
  open classical

  example : A :=
    by_contradiction
      (assume h : ¬ A,
        show false, from sorry)
end

2.4.5 Ejemplos

variables A B C : Prop

variable h1 : A  B
variable h2 : B  C

example : A  C :=
  assume h : A,
  show C, from h2 (h1 h)
example (A B C : Prop) : (A  (B  C))  (A  B  C) :=
  assume h1 : A  (B  C),
  assume h2 : A  B,
  show C, from h1 (and.left h2) (and.right h2)
example (A B C : Prop) : A  (B  C)  (A  B)  (A  C) :=
  assume h1 : A  (B  C),
  or.elim (and.right h1)
    (assume h2 : B,
      show (A  B)  (A  C),
        from or.inl (and.intro (and.left h1) h2))
    (assume h3 : C,
      show (A  B)  (A  C),
        from or.inr (and.intro (and.left h1) h3))
example (A B C : Prop) : A  (B  C)  (A  B)  (A  C) :=
  λ h1, or.elim (and.right h1)
    (λ h2, or.inl (and.intro (and.left h1) h2))
    (λ h3, or.inr (and.intro (and.left h1) h3))

2.5 Razonamiento hacia adelante

2.5.1 Uso de have

variables A B C : Prop

variable h1 : A  B
variable h2 : B  C

example : A  C :=
  assume h : A,
  have h3 : B, from h1 h,
  show C, from h2 h3
example (A B C : Prop) : (A  (B  C))  (A  B  C) :=
  assume h1 : A  (B  C),
  assume h2 : A  B,
  have h3 : A, from and.left h2,
  have h4 : B, from and.right h2,
  show C, from h1 h3 h4
example (A B C : Prop) : (A  (B  C))  (A  B  C) :=
  assume h1 : A  (B  C),
  assume h2 : A  B,
  have h3 : A, from and.left h2,
  have h4 : B, from and.right h2,
  have h5 : B  C, from h1 h3,
  show C, from h5 h4
example (A B : Prop) : A  B  B  A :=
  assume h1 : A  B,
  have h2 : A, from and.left h1,
  have h3 : B, from and.right h1,
  show B  A, from and.intro h3 h2
example (A B : Prop) : A  B  B  A :=
  λ h, and.intro (and.right h) (and.left h)
example (A B C : Prop) : C :=
  have h : A  B, from sorry,
  show C, from or.elim h
    (assume h1 : A,
      show C, from sorry)
    (assume h2 : B,
      show C, from sorry)
example (A B C : Prop) : A  (B  C)  (A  B)  (A  C) :=
  assume h1 : A  (B  C),
  have h2 : A, from and.left h1,
  have h3 : B  C, from and.right h1,
  show (A  B)  (A  C), from
    or.elim h3
      (assume h4 : B,
        have h5 : A  B, from and.intro h2 h4,
        show (A  B)  (A  C), from or.inl h5)
      (assume h6 : C,
        have h7 : A  C, from and.intro h2 h6,
        show (A  B)  (A  C), from or.inr h7)

2.6 Definiciones y teoremas

def triple_and (A B C : Prop) : Prop :=
  A  (B  C)
def triple_and (A B C : Prop) : Prop :=
  A  (B  C)

variables D E F G : Prop

#check triple_and (D  E) (¬F  G) (¬D)
-- | triple_and (D ∨ E) (¬F → G) (¬D) : Prop
def double (n : ) :  := n + n
theorem and_commute (A B : Prop) : A  B  B  A :=
  assume h, and.intro (and.right h) (and.left h)
theorem and_commute (A B : Prop) : A  B  B  A :=
  assume h, and.intro (and.right h) (and.left h)

variables C D E : Prop
variable h1 : C  ¬D
variable h2 : ¬D  C  E

example : E := h2 (and_commute C (¬D) h1)
theorem and_commute {A B : Prop} : A  B  B  A :=
  assume h, and.intro (and.right h) (and.left h)
theorem and_commute {A B : Prop} : A  B  B  A :=
  assume h, and.intro (and.right h) (and.left h)

variables C D E : Prop
variable h1 : C  ¬ D
variable h2 : ¬ D  C  E

example : E := h2 (and_commute h1)
theorem and_commute {A B : Prop} (h : A  B) : B  A :=
  and.intro (and.right h) (and.left h)
namespace hidden

variables {A B : Prop}

theorem or_resolve_left (h1 : A  B) (h2 : ¬A) : B :=
  or.elim h1
    (assume h3 : A, show B, from false.elim (h2 h3))
    (assume h4 : B, show B, from h4)

theorem or_resolve_right (h1 : A  B) (h2 : ¬B) : A :=
  or.elim h1
    (assume h3 : A, show A, from h3)
    (assume h4 : B, show A, from false.elim (h2 h4))

theorem absurd (h1 : ¬A) (h2 : A) : B :=
  false.elim (h1 h2)

end hidden

2.7 Sintaxis adicional

variables A B : Prop

example : A  A  B :=
  assume : A,
  show A  B, from or.inl this
variables A B : Prop

example : A  B  A  B :=
  assume : A,
  assume : B,
  show A  B, from and.intro ‹A› ‹B›
theorem my_theorem {A B C : Prop} :
  A  (B  C)  (A  B)  (A  C) :=
  assume h : A  (B  C),
  have A, from and.left h,
  have B  C, from and.right h,
  show (A  B)  (A  C), from
    or.elim ‹B  C›
      (assume : B,
        have A  B, from and.intro ‹A› ‹B›,
        show (A  B)  (A  C), from or.inl this)
      (assume : C,
        have A  C, from and.intro ‹A› ‹C›,
        show (A  B)  (A  C), from or.inr this)
example (A B : Prop) : A  B  B  A :=
  assume h : A  B,
  show B  A, from h.right, h.left

example (A B : Prop) : A  B  B  A :=
  assume h, h.right, h.left
example (A B : Prop) : A  B  B  A :=
  assume h₁, h₂, h₂, h₁
example (A B : Prop) : B  (A  B)  A :=
  assume hB, hAB,
  hAB.mpr hB
example (A B : Prop) : A  B  B  A :=
  assume h₁, h₂, h₂, h₁, 
   assume h₁, h₂, h₂, h₁
/- Este comentario
   tiene dos líneas. -/

example (A : Prop) : A  A :=
  assume : A,        -- supone el antececente
  show A, from this  -- lo usa para la conclusión

2.8 Ejercicios

variables A B C D : Prop

example : A  (A  B)  B :=
  assume h1: A  (A  B),
  have h2: A, from h1.left,
  have h3: A  B, from h1.right,
  show B, from h3 h2

example : A  ¬(¬A  B) :=
  assume h1: A,
  assume h2: ¬A  B,
  show false, from h2.left h1

example : ¬(A  B)  (A  ¬B) :=
  assume h1: ¬(A  B),
  assume h2: A,
  assume h3: B,
  show false, from h1 (and.intro h2 h3)

example (h₁ : A  B) (h₂ : A  C) (h₃ : B  D) : C  D :=
  or.elim h₁ 
    (assume h₄ : A,
      have C, from h₂ h₄,
      show C  D, from or.inl this)
    (assume h₄ : B,
      have D, from h₃ h₄,
      show C  D, from or.inr this)       

example (h : ¬A  ¬B) : ¬(A  B) :=
  assume h1 : A  B,
  or.elim h1
    (assume h2 : A,
      show false, from h.left h2)
    (assume h2 : B, 
      show false, from h.right h2)

example : ¬(A  ¬A) :=
  sorry

3 Razonamiento en lógica clásica

3.1 Demostración por contradicción

open classical

variable (A : Prop)

example : A :=
  by_contradiction
    (assume h : ¬ A,
      show false, from sorry)
open classical

variable (A : Prop)

example : A  ¬ A :=
  by_contradiction
    (assume h1 : ¬ (A  ¬ A),
      have h2 : ¬ A, from
        assume h3 : A,
        have h4 : A  ¬ A, from or.inl h3,
        show false, from h1 h4,
      have h5 : A  ¬ A, from or.inr h2,
      show false, from h1 h5)
open classical

example (A : Prop) : A  ¬ A :=
  or.elim (em A)
    (assume : A, or.inl this)
    (assume : ¬ A, or.inr this)

example (A : Prop) : A  ¬ A :=
  em A
open classical

example (A : Prop) : ¬¬A  A :=
  iff.intro
    (assume h1 : ¬¬A,
      show A, from by_contradiction
        (assume h2 : ¬A,
          show false, from h1 h2))
    (assume h3 : A,
      show ¬¬A, from 
        assume h2 : ¬A, h2 h3)

3.2 Algunos principios de la lógica clásica

open classical

variables (A B : Prop)

example (h : ¬B  ¬A) : A  B :=
  assume h1 : A,
  show B, from
    by_contradiction
      (assume h2 : ¬B,
        have h3 : ¬A, from h h2,
        show false, from h3 h1)
open classical

variables (A B : Prop)

example (h : ¬ (A  ¬ B)) : A  B :=
assume : A,
show B, from
  by_contradiction
    (assume : ¬ B,
      have A  ¬ B, from and.intro ‹A› this,
      show false, from h this)
open classical

variables (A B : Prop)

example : (A  B)  (B  A) :=
  or.elim (em B) 
    (assume h : B,
      have A  B, from
        assume : A,
        show B, from h,
      show (A  B)  (B  A),
        from or.inl this)
    (assume h : ¬ B,
      have B  A, from
        assume : B,
        have false, from h this,
        show A, from false.elim this,
      show (A  B)  (B  A),
        from or.inr this)

4 Semántica de la lógica proposicional

4.1 Valores de verdad y asignaciones

variables A B : Prop
variable hB : B

example : A  B :=
  assume hA : A,
    show B, from hB
variables A B : Prop
variable hnA : ¬ A

example : A  B :=
  assume hA : A,
    show B, from false.elim (hnA hA)
variables A B : Prop
variable hA : A
variable hnB : ¬B

example : ¬(A  B) :=
  assume h : A  B,
  have hB : B, from h hA,
  show false, from hnB hB
-- Definición de la interpretación
def A := tt
def B := ff
def C := tt
def D := tt
def E := ff

def test (p : Prop) [decidable p] : string :=
  if p then "true" else "false"

#eval test ((A  B)  ¬ C)     -- Da "false" 
#eval test (A  D)             -- Da "true"
#eval test (C  (D  ¬E))      -- Da "true"
#eval test (¬(A  B  C  D))  -- Da "true"

5 Lógica de primer orden en Lean

5.1 Funciones, predicados y relaciones

constant U : Type

constant c : U
constant f : U  U
constant g : U  U  U
constant P : U  Prop
constant R : U  U  Prop

variables x y : U

#check c              -- Da c : U
#check f c            -- Da f c : U
#check g x y          -- Da g x y : U
#check g x (f c)      -- Da g x (f c) : U 

#check P (g x (f c))  -- Da P (g x (f c)) : Prop
#check R x y          -- Da R x y : Prop
namespace hidden

constant mul :     
constant add :     
constant square :   
constant even :   Prop
constant odd :   Prop
constant prime :   Prop
constant divides :     Prop
constant lt :     Prop
constant zero : 
constant one : 

variables w x y z : 

#check mul x y
#check add x y
#check square x
#check even x

-- Declaración de operaciones infijas
infix + := add
infix * := mul
infix < := lt

end hidden
open nat

constant square :   
constant prime  :   Prop
constant even   :   Prop

variables w x y z : 

#check even (x + y + z)  prime ((x + 1) * y * y)
#check ¬ (square (x + y * z) = w)  x + y < z
#check x < y  even x  even y  x + 1 < y
variables Point Line : Type
variable  lies_on : Point  Line  Prop

#check  (p q : Point) (L M : Line),
        p  q  lies_on p L  lies_on q L  lies_on p M  
          lies_on q M  L = M

#check  p q L M, p  q  lies_on p L  lies_on q L  
  lies_on p M  lies_on q M  L = M

5.2 Reglas del cuantificador universal

open nat

constant prime :   Prop
constant even  :   Prop
constant odd   :   Prop

#check  x, (even x  odd x)  ¬ (even x  odd x)
#check  x, even x  2 ∣ x
#check  x, even x  even (x^2)
#check  x, even x  odd (x + 1)
#check  x, prime x  x > 2  odd x
#check  x y z, x ∣ y  y ∣ z  x ∣ z
variable U : Type
variable P : U  Prop

example :  y, P y :=
  assume x,
  show P x, from sorry

example :  x, P x :=
  assume y,
  show P y, from sorry
variable U : Type
variable P : U  Prop
variable h :  x, P x
variable a : U

example : P a :=
  show P a, from h a
variable U : Type
variables A B : U  Prop

example (h1 :  x, A x  B x) (h2 :  x, A x) :  x, B x :=
  assume y,
  have h3 : A y, from h2 y,
  have h4 : A y  B y, from h1 y,
  show B y, from h4 h3

-- Demostración simplificada
example (h1 :  x, A x  B x) (h2 :  x, A x) :  x, B x :=
  assume y,
  show B y, from h1 y (h2 y)
variable U : Type
variables A B : U  Prop

example : ( x, A x)  ( x, B x)  ( x, A x  B x) :=
  assume hA :  x, A x,
  assume hB :  x, B x,
  assume y,
  have Ay : A y, from hA y,
  have By : B y, from hB y,
  show A y  B y, from and.intro Ay By

-- Demostración con menos etiquetas
example : ( x, A x)  ( x, B x)  ( x, A x  B x) :=
  assume hA :  x, A x,
  assume hB :  x, B x,
  assume y,
  have A y, from hA y,
  have B y, from hB y,
  show A y  B y, from and.intro ‹A y› ‹B y› 

5.3 Reglas del cuantificador existencial

variable U : Type
variable P : U  Prop

example (y : U) (h : P y) :  x, P x :=
  exists.intro y h
variable U : Type
variable P : U  Prop
variable Q : Prop

example (h1 :  x, P x) (h2 :  x, P x  Q) : Q :=
  exists.elim h1
    (assume (y : U) (h : P y),
      have h3 : P y  Q, from h2 y,
      show Q, from h3 h)

-- 2ª demostración
example (h1 :  x, P x) (h2 :  x, P x  Q) : Q :=
  exists.elim h1 (assume y h, h2 y h)
variable U : Type
variables A B : U  Prop

example : ( x, A x  B x)   x, A x :=
  assume h1 :  x, A x  B x,
  exists.elim h1 
    (assume y (h2 : A y  B y),
      have h3 : A y, from and.left h2,
      show  x, A x, from exists.intro y h3)

-- Eliminación de paréntesis con $
example : ( x, A x  B x)   x, A x :=
  assume h1 :  x, A x  B x,
  exists.elim h1 $
    assume y (h2 : A y  B y),
    have h3 : A y, from and.left h2,
    show  x, A x, from exists.intro y h3
variable U : Type
variables A B : U  Prop

example : ( x, A x  B x)  ( x, A x)  ( x, B x) :=
  assume h1 :  x, A x  B x,
  exists.elim h1 $
    assume y (h2 : A y  B y),
    or.elim h2
      (assume h3 : A y, 
        have h4 :  x, A x, from exists.intro y h3,
        show ( x, A x)  ( x, B x), from or.inl h4)
      (assume h3 : B y, 
        have h4 :  x, B x, from exists.intro y h3,
        show ( x, A x)  ( x, B x), from or.inr h4)
variable U : Type
variables A B : U  Prop

example : ( x, A x  ¬ B x)  ¬  x, A x  B x :=
  assume h1 :  x, A x  ¬ B x,
  assume h2 :  x, A x  B x,
  exists.elim h2 $
    assume x (h3 : A x  B x),
    have h4 : A x, from and.left h3,
    have h5 : B x, from and.right h3,
    have h6 : ¬ B x, from h1 x h4,
    show false, from h6 h5
variable U : Type
variable u : U
variable P : Prop

example : (x : U, P)  P :=
  iff.intro
    (assume h1 : x, P, 
      exists.elim h1 $
        assume x (h2 : P),
        h2)
    (assume h1 : P, 
      exists.intro u h1)
variable U : Type
variables P R : U  Prop
variable Q : Prop

example (h1 : x, P x  R x) (h2 : x, P x  R x  Q) : Q :=
  let y, hPy, hRy := h1 in
  show Q, from h2 y hPy hRy

5.4 Igualdad y demostraciones ecuacionales

variable A : Type

variables x y z : A
variable P : A  Prop

example : x = x :=
  show x = x, from eq.refl x

example : y = x :=
  have h : x = y, from sorry,
  show y = x, from eq.symm h

example : x = z :=
  have h1 : x = y, from sorry,
  have h2 : y = z, from sorry,
  show x = z, from eq.trans h1 h2

example : P y :=
  have h1 : x = y, from sorry,
  have h2 : P x, from sorry,
  show P y, from eq.subst h1 h2
variables (A : Type) (x y z : A)

example : y = x  y = z  x = z :=
  assume h1 : y = x,
  assume h2 : y = z,
  have h3 : x = y, from eq.symm h1,
  show x = z, from eq.trans h3 h2

-- 2ª demostración
example : y = x  y = z  x = z :=
  assume h1 h2, eq.trans (eq.symm h1) h2

-- 3ª demostración (aplicativa con reescritura)
example : y = x  y = z  x = z :=
  assume h1 : y = x,
  assume h2 : y = z,
  show x = z, 
    begin
      rewrite ←h1,
      apply h2
    end

-- 4ª demostración
example : y = x  y = z  x = z :=
  assume h1 : y = x,
  assume h2 : y = z,
  show x = z, 
    begin
      rw ←h1,
      rw h2
    end

-- 5ª demostración (agrupando reescrituras)
example : y = x  y = z  x = z :=
  assume h1 : y = x,
  assume h2 : y = z,
  show x = z, 
    begin
      rw [←h1, h2]
    end

-- 6ª demostración (con by)
example : y = x  y = z  x = z :=
  assume h1 : y = x,
  assume h2 : y = z,
  show x = z, by rw [←h1, h2]

-- 7ª demostración (con cálculo ecuacional)
example : y = x  y = z  x = z :=
  assume h1 : y = x,
  assume h2 : y = z,
  calc
      x = y : eq.symm h1
    ... = z : h2 
import data.int.basic

variables x y z : int

example : x + 0 = x :=
  add_zero x

example : 0 + x = x :=
  zero_add x

example : (x + y) + z = x + (y + z) :=
  add_assoc x y z

example : x + y = y + x :=
  add_comm x y

example : (x * y) * z = x * (y * z) :=
  mul_assoc x y z

example : x * y = y * x :=
  mul_comm x y

example : x * (y + z) = x * y + x * z :=
  left_distrib x y z

example : (x + y) * z = x * z + y * z :=
  right_distrib x y z
import data.int.basic

example (x y z : int) : (x + y) + z = (x + z) + y :=
  calc
   (x + y) + z = x + (y + z) : add_assoc x y z
           ... = x + (z + y) : eq.subst (add_comm y z) rfl
           ... = (x + z) + y : eq.symm (add_assoc x z y)

-- 2ª demostración (con reescritura)
example (x y z : int) : (x + y) + z = (x + z) + y :=
  calc
    (x + y) + z = x + (y + z) : by rw add_assoc
            ... = x + (z + y) : by rw [add_comm y z]
            ... = (x + z) + y : by rw add_assoc

-- 3ª demostración
example (x y z : int) : (x + y) + z = (x + z) + y :=
  by rw [add_assoc, add_comm y z, add_assoc]
variables a b d c : int

example : (a + b) * (c + d) = a * c + b * c + a * d + b * d :=
calc
  (a + b) * (c + d) = (a + b) * c + (a + b) * d : by rw left_distrib
    ... = (a * c + b * c) + (a + b) * d         : by rw right_distrib
    ... = (a * c + b * c) + (a * d + b * d)     : by rw right_distrib
    ... = a * c + b * c + a * d + b * d         : by rw ←add_assoc

-- 2ª demostración
example : (a + b) * (c + d) = a * c + b * c + a * d + b * d :=
by rw [left_distrib, right_distrib, right_distrib, ←add_assoc]

5.5 Ejercicios

section
  variable A : Type
  variable f : A  A
  variable P : A  Prop
  variable h :  x, P x  P (f x)

  include h

  -- 1ª demostración aplicativa
  lemma ejercicio1 :  y, P y  P (f (f y)) :=
  begin
    intro,
    intro,
    apply h,
    apply h,
    exact a
  end

  #print ejercicio1

  -- 2ª demostración aplicativa
  lemma ejercicio1b :  y, P y  P (f (f y)) :=
  begin
    assume y a,
    apply h (f y) (h y a),
  end

  -- 1ª demostración declarativa
  lemma ejercicio1c :  y, P y  P (f (f y)) :=
    assume y a,
    (have h1 : P y  P (f y), from h y,
     have h2 : P (f y), from h1 a,
     have h3 : P (f y)  P (f (f y)), from h (f y),
     show P (f (f y)), from h3 h2)

   #print ejercicio1c

end
section
  variable U : Type
  variables A B : U  Prop

  -- 1ª demostración
  lemma ejercicio2a : ( x, A x  B x)   x, A x :=
    begin
      intro,
      intro,
      have h1 : A x  B x,
      apply (a x),
      apply h1.left,
    end

  -- 2ª demostración
  lemma ejercicio2b : ( x, A x  B x)   x, A x :=
  begin
    intro, 
    intro,
    apply (a x).left
  end

  -- 3ª demostración
  lemma ejercicio2c : ( x, A x  B x)   x, A x :=
    λ a x, (a x).left

  -- 4ª demostración
  lemma ejercicio2d : ( x, A x  B x)   x, A x :=
    assume h1 :  x, A x  B x,
    ( assume x : U, 
      have h2 : A x  B x, from h1 x,
      show A x, from h2.left)

end
section
  variable U : Type
  variables A B C : U  Prop

  variable h1 :  x, A x  B x
  variable h2 :  x, A x  C x
  variable h3 :  x, B x  C x

  include h1 h2 h3

  lemma ejercicio3a :  x, C x :=
  begin
    intro,
    have h4 : A x  B x := h1 x,
    cases h4,
      apply h2 x,
      exact h4,
    apply h3 x,
    exact h4    
  end

end

José A. Alonso

2020-09-10 jue 06:52