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

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

-- This module contains some examples showing the use of the ATPs for
-- proving first-order logic theorems.

module FOL.TheoremsATP where

open import FOL.Base

------------------------------------------------------------------------------
-- 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
           ψ
-}

postulate
  ∀-intro : ((x : D)   x)   x   x
  ∀-intro' : ((x : D)   x)   
  ∀-elim  : (t : D)  (∀ x   x)   t
  ∀-elim' : (t : D)      t
  ∃-intro : (t : D)   t   
  ∃-elim  :    ((x : D)   x  A)  A
{-# ATP prove ∀-intro #-}
{-# ATP prove ∀-intro' #-}
{-# ATP prove ∀-elim #-}
{-# ATP prove ∀-elim' #-}
{-# ATP prove ∃-intro #-}
{-# ATP prove ∃-elim #-}

-- Generalization of De Morgan's laws.
postulate
  gDM₁ : ¬ (∀ x   x)  (∃[ x ] ¬ ( x))
  gDM₂ : ¬ ( )        (∀ x  ¬ ( x))
  gDM₃ : (∀ x   x)    ¬ (∃[ x ] ¬ ( x))
  gDM₄ :              ¬ (∀ x  ¬ ( x))
{-# ATP prove gDM₁ #-}
{-# ATP prove gDM₂ #-}
{-# ATP prove gDM₃ #-}
{-# ATP prove gDM₄ #-}

-- The order of quantifiers of the same sort is irrelevant.
postulate
  ∀-ord : (∀ x y   x y)  (∀ y x   x y)
  ∃-ord : (∃[ x ] ∃[ y ]  x y)  (∃[ y ] ∃[ x ]  x y)
{-# ATP prove ∀-ord #-}
{-# ATP prove ∃-ord #-}

-- Quantification over a variable that does not occur can be erased or
-- added.
postulate ∃-erase-add : (∃[ x ] A   x)  A  (∃[ x ]  x)
{-# ATP prove ∃-erase-add #-}

-- Distributes laws for the quantifiers.
postulate
  ∀-dist : (∀ x   x   x)  ((∀ x   x)  (∀ x   x))
  ∃-dist : (∃[ x ] ( x   x))  (    )
{-# ATP prove ∀-dist #-}
{-# ATP prove ∃-dist #-}

-- Interchange of quantifiers.
-- The related theorem ∀x∃y.Axy → ∃y∀x.Axy is not (classically) valid.
postulate ∃∀ : ∃[ x ] (∀ y   x y)   y  ∃[ x ]  x y
{-# ATP prove ∃∀ #-}

-- ∃ in terms of ∀ and ¬.
postulate
  ∃→¬∀¬ : ∃[ x ]  x  ¬ (∀ {x}  ¬  x)
  ∃¬→¬∀ : ∃[ x ] ¬  x  ¬ (∀ {x}   x)
{-# ATP prove ∃→¬∀¬ #-}
{-# ATP prove ∃¬→¬∀ #-}

-- ∀ in terms of ∃ and ¬.
postulate
  ∀→¬∃¬ : (∀ {x}   x)  ¬ (∃[ x ] ¬  x)
  ∀¬→¬∃ : (∀ {x}  ¬  x)  ¬ (∃[ x ]  x)
{-# ATP prove ∀→¬∃¬ #-}
{-# ATP prove ∀¬→¬∃ #-}

-- Distribution of ∃ and ∨.
postulate ∃∨ : ∃[ x ]( x   x)  (∃[ x ]  x)  (∃[ x ]  x)
{-# ATP prove ∃∨ #-}