{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
#ifdef LANGUAGE_PTS_HAS_SIGMA
#ifdef LANGUAGE_PTS_HAS_BOOL
#ifdef LANGUAGE_PTS_HAS_NAT
#define SIGMA_EXAMPLES
#endif
#endif
#endif
module Language.PTS.Examples.Sigma (
#ifdef SIGMA_EXAMPLES
eitherScript,
pairScript,
#endif
) where
#ifdef SIGMA_EXAMPLES
import Language.PTS
import Language.PTS.Bound
eitherScript :: forall s m. Script s m => m ()
eitherScript = do
let one = TermNatS (Inf TermNatZ)
let two = TermNatS (Inf one)
comment_ "If we have Booleans and dependent pair, we can make Either"
section_ "Boolean prelude"
define_ "if"
$$ forall_ "r" (TermBool ~> "r" ~> "r" ~> "r")
$$ lams_ ["r", "b", "t", "f"]
(Inf $ TermBoolElim "_" (liftH "r") "t" "f" "b")
comment_ "We a need variant in higher universe too"
define_ "if1"
$$ pi_ "r" (sort_ typeSortSort) (TermBool ~> "r" ~> "r" ~> "r")
$$ lams_ ["r", "b", "t", "f"]
(Inf $ TermBoolElim "_" (liftH "r") "t" "f" "b")
section_ "Type"
define_ "Either"
$$ sort_ typeSort ~> sort_ typeSort ~> sort_ typeSort
$$ lams_ ["A", "B"] (Inf $ Sigma "t" TermBool $ abstract1HSym "x" $ "if1" @@ sort_ typeSort @@ "x" @@ "A" @@ "B")
subsection_ "Example"
defineInf_ "A" $ "Either" @@@ TermBool @@@ TermNat
example_ "A"
section_ "Constructors"
define_ "left"
$$ foralls_ ["A", "B"] ("A" ~> "Either" @@ "A" @@ "B")
$$ lams_ ["A","B","x"] (Pair (Inf TermTrue) "x")
define_ "right"
$$ foralls_ ["A", "B"] ("B" ~> "Either" @@ "A" @@ "B")
$$ lams_ ["A","B","y"] (Pair (Inf TermFalse) "y")
subsection_ "Examples"
define_ "x"
$$ "A"
$$ "left" @@@ TermBool @@@ TermNat @@@ TermTrue
define_ "y"
$$ "A"
$$ "left" @@@ TermBool @@@ TermNat @@@ TermFalse
define_ "u"
$$ "A"
$$ "right" @@@ TermBool @@@ TermNat @@@ one
define_ "v"
$$ "A"
$$ "right" @@@ TermBool @@@ TermNat @@@ two
example_ "x"
example_ "y"
example_ "u"
example_ "v"
section_ "Non-dependent elimination"
let eitherBody :: TermInf s Sym
eitherBody = TermBoolElim
"t" (abstract1HSym "t" $ "if1" @@ sort_ typeSort @@ "t" @@ "A" @@ "B" ~> "C")
(lam_ "x" $ "f" @@ "x")
(lam_ "y" $ "g" @@ "y")
"t"
define_ "either"
$$ foralls_ ["A","B","C"] (("A" ~> "C") ~> ("B" ~> "C") ~> "Either" @@ "A" @@ "B" ~> "C")
$$ lams_ ["A","B","C","f","g","e"]
(Match "e" "t" "v" $ abstract2HSym "t" "v" $ eitherBody @@ "v")
subsection_ "Example"
define_ "boolToNat"
$$ TermBool ~> TermNat
$$ lam_ "b" ("if" @@@ TermNat @@ "b" @@ Inf TermNatZ @@ Inf one)
define_ "toNat"
$$ "A" ~> TermNat
$$ "either" @@@ TermBool @@@ TermNat @@@ TermNat
@@ "boolToNat"
@@ lam_ "n" (Inf $ TermNatS "n")
example_ $ "toNat" @@ "x"
example_ $ "toNat" @@ "y"
example_ $ "toNat" @@ "u"
example_ $ "toNat" @@ "v"
section_ "Reduction"
comment_ "Note how much type annotations we don't have to write in Haskell"
define_ "redex1"
$$ foralls_ ["A","B","C"] (("A" ~> "C") ~> ("B" ~> "C") ~> "A" ~> "C")
$$ lams_ ["A","B","C","f","g","x"] ("either" @@ "A" @@ "B" @@ "C" @@ "f" @@ "g" @@ ("left" @@ "A" @@ "B" @@ "x"))
comment_ "it reduces!"
example_ "redex1"
define_ "redex2"
$$ foralls_ ["A","B","C"] (("A" ~> "C") ~> ("B" ~> "C") ~> "B" ~> "C")
$$ lams_ ["A","B","C","f","g","y"] ("either" @@ "A" @@ "B" @@ "C" @@ "f" @@ "g" @@ ("right" @@ "A" @@ "B" @@ "y"))
example_ "redex2"
pairScript :: forall s m. Script s m => m ()
pairScript = do
comment_ "Non dependent pair"
section_ "Type"
define_ "Pair"
$$ sort_ typeSort ~> sort_ typeSort ~> sort_ typeSort
$$ lams_ ["A", "B"] (Inf $ Sigma "_" "A" $ liftH "B")
section_ "Constructor"
define_ "mkPair"
$$ foralls_ ["A","B"] ("A" ~> "B" ~> "Pair" @@ "A" @@ "B")
$$ lams_ ["A","B","x","y"] (Pair "x" "y")
section_ "Projections"
define_ "fst"
$$ foralls_ ["A","B"] ("Pair" @@ "A" @@ "B" ~> "A")
$$ lams_ ["A","B","p"] (Match "p" "x" "y" $ abstract2HSym "x" "y" "x")
define_ "snd"
$$ foralls_ ["A","B"] ("Pair" @@ "A" @@ "B" ~> "B")
$$ lams_ ["A","B","p"] (Match "p" "x" "y" $ abstract2HSym "x" "y" "y")
section_ "Reduction"
define_ "redex1"
$$ foralls_ ["A","B"] ("A" ~> "B" ~> "A")
$$ lams_ ["A","B","x","y"] ("fst" @@ "A" @@ "B" @@ ("mkPair" @@ "A" @@ "B" @@ "x" @@ "y"))
example_ "redex1"
define_ "redex2"
$$ foralls_ ["A","B"] ("A" ~> "B" ~> "B")
$$ lams_ ["A","B","x","y"] ("snd" @@ "A" @@ "B" @@ ("mkPair" @@ "A" @@ "B" @@ "x" @@ "y"))
example_ "redex2"
#endif