------------------------------------------------------------------------------
-- First-order logic theorems
------------------------------------------------------------------------------

{-# OPTIONS --exact-split              #-}
{-# OPTIONS --no-sized-types           #-}
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --without-K                #-}

module FOL.TheoremsI where

-- The theorems below are valid on intuitionistic logic and with an
-- empty domain.
open import FOL.Base hiding ( D≢∅ ; pem )

------------------------------------------------------------------------------
-- We postulate some formulae and propositional functions.
postulate
  A     : Set
    : D  Set
      : D  D  Set

-- The introduction and elimination rules for the quantifiers are theorems.
{-
      φ(x)
  -----------  ∀-intro
    ∀x.φ(x)

    ∀x.φ(x)
  -----------  ∀-elim
     φ(t)

      φ(t)
  -----------  ∃-intro
    ∃x.φ(x)

   ∃x.φ(x)   φ(x) → ψ
 ----------------------  ∃-elim
           ψ
-}

∀-intro : ((x : D)   x)   x   x
∀-intro h = h

∀-intro' : ((x : D)   x)   
∀-intro' = dfun

∀-elim : (t : D)  (∀ x   x)   t
∀-elim t h = h t

∀-elim' : (t : D)      t
∀-elim' = dapp

∃-intro : (t : D)   t   
∃-intro t A¹x = t , A¹x

∃-elim :    ((x : D)   x  A)  A
∃-elim (x , A¹x) h = h x A¹x

-- Generalization of De Morgan's laws.
gDM₂ : ¬ ( )  (∀ {x}  ¬ ( x))
gDM₂ = l→r , r→l
  where
  l→r : ¬ ( )   {x}  ¬ ( x)
  l→r h A¹x = h (_ , A¹x)

  r→l : (∀ {x}  ¬ ( x))  ¬ ( )
  r→l h (x , A¹x) = h A¹x

gDM₂' : ¬ ( )  (⋀[ x ] ¬ ( x))
gDM₂' = fun l→r , fun r→l
  where
  l→r : ¬ ( )  ⋀[ x ] ¬  x
  l→r h = dfun  d A¹d  h (d , A¹d))

  r→l : ⋀[ x ] ¬  x  ¬  
  r→l (dfun f) (x , A¹x) = f x A¹x

-- Quantification over a variable that does not occur can be erased or
-- added.
∃-erase-add : (∃[ x ] A   x)  A  (∃[ x ]  x)
∃-erase-add = l→r , r→l
  where
  l→r : ∃[ x ] A   x  A  (∃[ x ]  x)
  l→r (x , a , A¹x) = a , x , A¹x

  r→l : A  (∃[ x ]  x)  ∃[ x ] A   x
  r→l (a , x , A¹x) = x , a , A¹x

-- Interchange of quantifiers.
-- The related theorem ∀x∃y.Axy → ∃y∀x.Axy is not (classically) valid.
∃∀ : ∃[ x ] (∀ y   x y)   y  ∃[ x ]  x y
∃∀ (x , h) y = x , h y

-- ∃ in terms of ∀ and ¬.
∃→¬∀¬ : ∃[ x ]  x  ¬ (∀ {x}  ¬  x)
∃→¬∀¬ (_ , A¹x) h = h A¹x

∃¬→¬∀ : ∃[ x ] ¬  x  ¬ (∀ {x}   x)
∃¬→¬∀ (_ , h₁) h₂ = h₁ h₂

-- ∀ in terms of ∃ and ¬.
∀→¬∃¬ : (∀ {x}   x)  ¬ (∃[ x ] ¬  x)
∀→¬∃¬ h₁ (_ ,  h₂) = h₂ h₁

∀¬→¬∃ : (∀ {x}  ¬  x)  ¬ (∃[ x ]  x)
∀¬→¬∃ h₁ (_ , h₂) = h₁ h₂

-- Distribution of ∃ and ∨.
∃∨ : ∃[ x ]( x   x)  (∃[ x ]  x)  (∃[ x ]  x)
∃∨ (x , inj₁ A¹x) = inj₁ (x , A¹x)
∃∨ (x , inj₂ B¹x) = inj₂ (x , B¹x)