#ifdef LANGUAGE_PTS_HAS_EQUALITY
#ifdef LANGUAGE_PTS_HAS_BOOL
#ifdef LANGUAGE_PTS_HAS_NAT
#ifdef LANGUAGE_PTS_HAS_SIGMA
#ifdef LANGUAGE_PTS_HAS_PROP
#define EQUALITY_EXAMPLES
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
#endif
#endif
#endif
#endif
#endif
module Language.PTS.Examples.Equality (
#ifdef EQUALITY_EXAMPLES
equalityScript,
equivalenceScript,
leibnizScript,
inequalityScript,
#endif
) where
#ifdef EQUALITY_EXAMPLES
import Language.PTS
import Language.PTS.Bound
equalityScript :: forall s m. Script s m => m ()
equalityScript = do
section_ "Non-dependent elimination: if"
define_ "if"
$$ forall_ "r" (TermBool ~> "r" ~> "r" ~> "r")
$$ lams_ ["r", "b", "t", "f"]
(Inf $ TermBoolElim "_" (liftH "r") "t" "f" "b")
section_ "Negation, not"
define_ "not"
$$ TermBool ~> TermBool
$$ lam_ "b" ("if" @@@ TermBool @@ "b" @@@ TermFalse @@@ TermTrue)
example_ "not"
example_ $ "not" @@@ TermTrue
example_ $ "not" @@@ TermFalse
section_ "Simple equality examples"
example_ $$ Refl -:-
Equality TermBool ("not" @@@ TermTrue) (Inf TermFalse)
example_ $$ Refl -:-
Equality TermBool ("not" @@@ TermFalse) (Inf TermTrue)
section_ "Lemma: Not is involutive"
let ty b = Equality TermBool b ("not" @@ ("not" @@ b))
define_ "not-inv"
$$ pi_ "b" TermBool (ty "b")
$$ lam_ "b" (Inf $ TermBoolElim "x" (abstract1HSym "x" $ ty "x") Refl Refl "b")
section_ "Example with exists"
let ty2 :: TermInf s Sym -> TermInf s Sym
ty2 x = sigma_ "y" TermBool (Equality TermBool (Inf x) ("not" @@ "y"))
define_ "not-surj"
$$ pi_ "x" TermBool (ty2 "x")
$$ lam_ "x" (Inf $ TermBoolElim "b" (abstract1HSym "b" $ ty2 "b")
(Pair (Inf TermFalse) Refl)
(Pair (Inf TermTrue) Refl)
"x")
equivalenceScript :: forall s m. Script s m => m ()
equivalenceScript = do
section_ "Symmetry"
define_ "SYM"
$$ sort_ typeSort ~> sort_ typeSort
$$ lam_ "A" (pi_ "x" "A" $ pi_ "y" "A" $ Equality "A" "x" "y" ~> Equality "A" "y" "x")
let j_ u v w a p = J (V3 (IrrSym u) (IrrSym v) (IrrSym w)) a (abstract3HSym u v w p)
define_ "sym"
$$ forall_ "A" ("SYM" @@ "A")
$$ lams_ ["A","x","y","p"]
(Inf $ j_ "u" "v" "w" "A" (Equality "A" "v" "u") (lam_ "q" Refl) "x" "y" "p")
subsection_ "Example"
define_ "nat-fold"
$$ forall_ "r" (TermNat ~> ("r" ~> "r") ~> "r" ~> "r")
$$ lams_ ["r", "n", "s", "z"]
(Inf $ TermNatElim "_" (liftH "r") "z" (lam_ "l" "s") "n")
define_ "succ"
$$ TermNat ~> TermNat
$$ lam_ "n" (Inf $ TermNatS "n")
define_ "plus"
$$ TermNat ~> TermNat ~> TermNat
$$ lams_ ["x", "y"] ("nat-fold" @@@ TermNat @@ "x" @@ "succ" @@ "y")
example_ $ Refl -:- Equality TermNat (3 + 1) (1 + 3)
example_ $ "sym" @@@ TermNat @@ 3 + 1 @@ 1 + 3 @@ Refl
section_ "Transitivity"
define_ "TRANS"
$$ sort_ typeSort ~> sort_ typeSort
$$ lam_ "A" (pi_ "x" "A" $ pi_ "y" "A" $ pi_ "z" "A" $ Equality "A" "x" "y" ~> Equality "A" "y" "z" ~> Equality "A" "x" "z")
define_ "trans"
$$ forall_"A" ("TRANS" @@ "A")
$$ lams_ ["A","x","y","z","p"]
(Inf $ j_ "u" "v" "w" "A" (Equality "A" "v" "z" ~> Equality "A" "u" "z") (lams_ ["_", "r"] "r") "x" "y" "p")
example_ $ "trans" @@@ TermNat @@ 1 + 3 @@ 2 + 2 @@ 3 + 1 @@ Refl
inequalityScript :: forall s m. Script s m => m ()
inequalityScript = do
comment_ "Proving inequalities is difficult!"
define_ "if1"
$$ pi_ "r" (sort_ typeSortSort) (TermBool ~> "r" ~> "r" ~> "r")
$$ lams_ ["r", "b", "t", "f"]
(Inf $ TermBoolElim "_" (liftH "r") "t" "f" "b")
comment_ "Important thing is to find proper motive for induction"
let motive u v = "if1" @@ sort_ typeSort @@ u @@ ("if1" @@ sort_ typeSort @@ v @@@ Unit @@@ Empty) @@@ Unit
define_ "motive"
$$ TermBool ~> TermBool ~> sort_ typeSort
$$ lams_ ["u","v"] (motive "u" "v")
comment_ "With proper motive, proof is almost trivial"
let j_ u v w a p = J (V3 (IrrSym u) (IrrSym v) (IrrSym w)) a (abstract3HSym u v w p)
define_ "true-is-not-false"
$$ Equality TermBool (Inf TermTrue) (Inf TermFalse) ~> Empty
$$ lams_ ["p"]
(Inf $ j_ "u" "v" "w" TermBool
("motive" @@ "u" @@ "v")
(lam_ "b" $ Inf $ TermBoolElim "c" (abstract1HSym "c" $ "motive" @@ "c" @@ "c") (Inf I) (Inf I) "b")
(Inf TermTrue) (Inf TermFalse) "p")
example_ "true-is-not-false"
leibnizScript :: forall s m. Script s m => m ()
leibnizScript = do
section_ "Leibniz"
comment_ "We can define Leibniz equality"
comment_ "in the systems with impredicative bottom universe."
comment_ "TODO: define CComega, and make conversions"
define_ "Leibniz"
$$ pi_ "A" (sort_ typeSort) ("A" ~> "A" ~> sort_ typeSort)
$$ lams_ ["A","x","y"] (pi_ "C" ("A" ~> sort_ typeSort) $ "C" @@ "x" ~> "C" @@ "y")
subsection_ "Reflexivity"
define_ "REFL"
$$ sort_ typeSort ~> sort_ typeSort
$$ lam_ "A" (pi_ "x" "A" $ "Leibniz" @@ "A" @@ "x" @@ "x")
define_ "refl1"
$$ forall_ "A" ("REFL" @@ "A")
$$ lams_ ["A","x","C","Cx"] "Cx"
subsection_ "Symmetry"
define_ "SYM"
$$ sort_ typeSort ~> sort_ typeSort
$$ lam_ "A" (pi_ "x" "A" $ pi_ "y" "A" $ "Leibniz" @@ "A" @@ "x" @@ "y" ~> "Leibniz" @@ "A" @@ "y" @@ "x")
define_ "sym"
$$ forall_ "A" ("SYM" @@ "A")
$$ lams_ ["A","x","y","xy"]
("xy" @@ lam_ "z" ("Leibniz" @@ "A" @@ "z" @@ "x") @@ ("refl1" @@ "A" @@ "x"))
subsection_ "Transitivity"
comment_ "An exercise!"
#endif