ã¿ãªããããã«ã¡ã¯ã
Shapelessã䜿çšããŠRockã§èšè¿°ããã
ProvingGroundã©ã€ãã©ãªã䜿çšããç§ã®çµéšãå
±æããããšæããŸãã ã©ã€ãã©ãªã«ã¯
ããã¥ã¡ã³ãããã
ãŸãã ãããã»ã©åºç¯å²ã§ã¯ãããŸããã å³æžé€šã®èè
ã¯ãã€ã³ãç§åŠç 究æã®
ã·ãããŒã«ã¿ã¬ãžã«ã§ãã ã©ã€ãã©ãªã¯å®éšçã§ãã ã·ãããŒã«ã¿èªèº«ã¯ãããã¯ãŸã å³æžé€šã§ã¯ãªãããé²è¡äžã®äœæ¥ãã ãšèšã£ãŠããŸãã ã©ã€ãã©ãªã®ã°ããŒãã«ãªç®æšã¯ãçããŠããæ°åŠè
ããèšäºãåãåºããããã¹ãã解æããèªç¶èšèªãåŒã§å€æããŠãã³ã³ãã€ã©ããã§ãã¯ã§ãã圢åŒçãªèšŒæã«ããããšã§ãã ããã¯ãŸã éåžžã«é ãããšã¯æããã§ãã ãããŸã§ã®ãšãããã©ã€ãã©ãªã§ã¯ãäŸååããã³ãã¢ãããŒåçè«ïŒ
HoTT ïŒã®åºæ¬ã䜿çšããŠãïŒåïŒå®çãèªåçã«èšŒæã§ããŸãã
ããã¯ãã¹ãŠãStepikaã³ã³ãã¹ãã®Rockã§äŸååã«é¢ããå
¥é
ã³ãŒã¹ãèšé²ãããã£ããšããäºå®ããå§ãŸããŸããã ç¹°ãè¿ããããããŸããã§ããããæè¿ãã€ããªã¹ã«è¯ã
ã³ãŒã¹ãç»å ŽããŸããã Scalaã¯ãæãäžè¬çãªé¢æ°åèšèªã®1ã€ãšããŠéžã°ããŸããã ãScalaãããdependent typesãããHoTTãããã³æãææãªå€èŠ³ã®ProvingGroundã«åŸã£ãŠgithubã§Googleãæ€çŽ¢ããŸããã ããã«å
責äºé
-ç¹å®ã®èšèªãã©ã€ãã©ãªããäŸååã䜿çšããããã°ã©ãã³ã°ãèªåå®çã®èšŒæãHoTTã®æäœã«æãé©ããŠãããšã¯äž»åŒµããŸããã ä»ã®èšèªãã©ã€ãã©ãªã䜿çšããããšãã§ããŸã-å¥ã®ã³ãŒã¹ããããŸãã
ãåãã®ããã«ãScalaã¯äŸååã®ãµããŒããå¶éãããŠããèšèªã§ãã äŸååã¯ã
ãã¹äŸåå ã
åã¬ãã«å€ãããã³
å«æã䜿çšããŠå®è£
ãããŸãïŒ
å¥ã®èŠ³ç¹ããšãã¥ã¬ãŒããããŸãïŒã ãã¢ããã¯ãŸãã¯ããã¯ãã©ã¹ã·ã§ã€ãã¬ã¹ã®äŸååã説æããåãã©ã¡ãŒã¿ãŒïŒãžã§ããªãã¯ïŒããã®åã¡ã³ããŒã®
éã ãå«æããã¹äŸååã
ãè£å©ããã¿ãŒã³ ãåã¬ãã«ã®èšç®ãªã©ã®æè¡ç詳现ã«è¡ãè©°ãŸããŸãã ç§ã¯æ¬åœã«ããããããŸããã§ããã ãããã£ãŠãã³ãŒã¹ã®äžéšã¯ããåºãã®ããã¯ã§è¡ãããŸããããç·Žç¿ã®ã»ãšãã©ã¯ProvingGroundã§è¡ãããŸããã
çšèªãšçš®é¡
å€æ°ãçšèªãã¿ã€ããé¢æ°ãªã©ãèšå®ããã«ã¯ ProvingGroundã¯
DSLãæäŸããŸãã
ãããã£ãŠãã¿ã€ã
A
ãšãã®ã¿ã€ãã®å€æ°ã宣èšã§ããŸãã
val A = "A" :: Type val a = "a" :: A
ã€ãŸã å
žåçãªåºåã¯æ¬¡ã®ããã«ãªããŸã
val _ = " " :: _
.fansi
ã¡ãœããã䜿çšããŠãçŸããããšããçšèªã
.fansi
ãã
.fansi
ã䜿çšããŠãã®ã¿ã€ããå°å·ã§ã
.fansi
ã
println(a) > a : (A : U_0) println(a.fansi) > a println(a.typ) > A : U_0 println(a.typ.fansi) > A
å€æ°ããã詳现ã«èšå®ã§ããŸãã
val a : Term = "a" :: A
ããã§ã
A
ã¯ProvingGroundã©ã€ãã©ãªã®ã¿ã€ãã§ãã
HoTTã¯ã¿ã€ãã§ããã
Term
ã¯Scalaã®ã¿ã€ãã§ãã
ãã®ãããå€æ°ãèšå®ããå Žåã
::
åŸã«åãèšè¿°ãããã§ã«çšèªãããå Žåã¯ããã®åã
!:
確èªã§ã
!:
a !: A
ãã®è¡ãã³ã³ãã€ã«ãããŠãããšããäºå®ã¯ãã¿ã€ããæ£ããæå®ãããŠããããšãæå³ããŸãã
äŸåå
ã¿ã€ããå°ãæãåºããŠãã ããã å€ããããã¿ã€ãããããŸãã åå€ã«ã¯ã¿ã€ãããããŸãã
äŸååã¯ãå€
äŸåå ïŒå¥ã®åã®ïŒã§ãã ããšãã°ã2è¡ã®ãªã¹ããš3è¡ã®ãªã¹ãã¯ãåãã¿ã€ãã®å€ïŒè¡ã®ãªã¹ãïŒã§ãã ããããèŠçŽ ã®æ°ã«é¢ããæ
å ±ãåã¬ãã«ã«æž¡ããšãåŸå±å-ãã¯ãã«ïŒå€ã«äŸå-èªç¶æ°ïŒãåŸãããŸãã ãŸãã2è¡ã®ãã¯ãã«ãš3è¡ã®ãã¯ãã«ã¯ç°ãªãã¿ã€ãã§ãã äŸååã®ä»ã®äŸãšããŠã¯ããŒã以å€ã®æ°å€ã空ã§ãªããªã¹ãã2çªç®ã®æ°å€ãæåã®æ°å€ããå°ããæ°å€ã®ãã¢ãçå€ã¿ã€ã
1 =:= 2
ïŒå€ãªãïŒãã¿ã€ã
1 =:= 1
2 =:= 2
ïŒãã1ã€ã®å€ïŒãªã©
ãããã£ãŠãã¿ã€ã
A
ã®å€ãšãã®ã¿ã€ãã®å€æ°ã«äŸåããäŸåã¿ã€ã
Ba
èšå®ã§ããŸãã
val Ba = "B(_ : A)" :: A ->: Type val b = "b" :: Ba(a)
æ©èœ
次ã«ç¢å°ã«ã€ããŠã æ©èœã®ç¢å°ã«ã¯ãäž»ã«4ã€ã®ã¿ã€ãããã
~>:
->:
~>:
ã
->:
~>:
å·ŠåŽã«ã³ãã³ã-ã©ã ãïŒã€ãŸãé¢æ°èªäœïŒã«ãå³åŽã«ã³ãã³ã-é¢æ°ã®ã¿ã€ãã«ã ãã€ãã³ã䜿çš-éåžžã®é¢æ°ã®å Žåããã«ãã䜿çš-äŸåé¢æ°ã®å ŽåïŒã€ãŸããå€ã ãã§ãªãå€ã®ã¿ã€ããåŒæ°ã«äŸåããŸãïŒã äŸãšããŠãåäžã®æ©èœ
val id = A :~> (a :-> a) !: A ~>: (A ->: A)
åãã§ãã¯ã®äžéšã¯å®è¡æã«è¡ãããŸãããScalaã³ã³ãã€ã©ãŒã¯åæ
å ±ã®äžéšã確èªããŸãã
val f : FuncLike[Term, Term] = a :~> b !: a ~>: Ba(a) val f : Term => Term = a :~> b !: a ~>: Ba(a)
ããã§ã¯ãRockã®ProvingGround / HoTTã³ã³ãã€ã©ã®åŸå±é¢æ°ã¿ã€ãã¯ãRockã®éåžžã®é¢æ°ãšèŠãªããŠããŸãã
èªå°å
èªå°ã¿ã€ããæå®ã§ããŸãã ããšãã°ãã³ã³ã¹ãã©ã¯ã¿ãŒããtrueãããã³ãfalseãã§ããããŒã«åïŒ
val Bool = "Boolean" :: Type val BoolInd = ("true" ::: Bool) |: ("false" ::: Bool) =: Bool val tru :: fls :: HNil = BoolInd.intros
ã€ãŸããå
žåçãªèªå°åã®ä»äºã¯æ¬¡ã®ããã«ãªããŸã
val _ = (...) |: (...) |: (...) =: _
ãã®ã¿ã€ãã®å€ã³ã³ã¹ãã©ã¯ã¿ãŒã¯
|:
åºåãã
|:
å¥ã®äŸã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãããŒããããã³ãèªç¶
n
åŸã®æ¬¡ã®æ°å€ããæã€èªç¶æ°ã®ã¿ã€ãã§ãã
val Nat = "Nat" :: Type val NatInd = ("0" ::: Nat) |: ("succ" ::: Nat -->>: Nat) =: Nat val zero :: succ :: HNil = NatInd.intros val one = succ(zero) !: Nat val two = succ(one) !: Nat
ã³ã³ã¹ãã©ã¯ã¿ãŒãplus integer
n
ãããã³ãminus integer
n
minus 1ããæã€æŽæ°ã®ã¿ã€ãã¯ããã§ã«å®çŸ©ãããŠããæŽæ°ã®ã¿ã€ãã䜿çšããŸãã
val Int = "Integer" :: Type val IntInd = ("pos" ::: Nat ->>: Int) |: ("neg" ::: Nat ->>: Int) =: Int val pos :: neg :: HNil = IntInd.intros
ã¿ã€ã
A
ã®å€ã®ã¿ã€ããªã¹ãã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã空ã®ãªã¹ãããšãã¿ã€ã
A
ããããšã¿ã€ã
ListA
ããŒã«ãæã€ãªã¹ããããããŸãã
val ListA = "List(A)" :: Type val ListAInd = ("nil" ::: ListA) |: ("cons" ::: A ->>: ListA -->>: ListA) =: ListA val nil :: cons :: HNil = ListAInd.intros
ãã€ããªããªãŒã¿ã€ãïŒç°¡åã«ãããããããŒãã«ç¹å®ã®ã¿ã€ãã®å€ãæããªãïŒã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒããªãŒãããšããã©ãŒã¯ãããããŸãïŒ2çªç®ã¯ãµãããªãŒã®ãã¢ãåããŸãïŒã
val BTree = "BTree" :: Type val BTreeInd = ("leaf" ::: BTree) |: ("fork" ::: BTree -->>: BTree -->>: BTree) =: BTree val leaf :: fork :: HNil = BTreeInd.intros
ãããã¯ããã©ã°ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãåã1ã€ã®ãµãããªãŒã«å€æããçå®ãå¥ã®ãµãããªãŒã«å€æããé¢æ°ãåãããšãã§ããŸãã
val BTree = "BTree" :: Type val BTreeInd = ("leaf" ::: BTree) |: ("fork" ::: (Bool -|>: BTree) -->>: BTree) =: BTree val leaf :: fork :: HNil = BTreeInd.intros
äŸåããèªå°å
åã
ã€ã³ããã¯ã¹ä»ãèªå°å ãããšãã°
Vec
ãã¯ãã«ãŸãã¯çå€å
Id
å Žåã
=::
代ããã«
=:
ãã«ãä»ã
=:
ç¢å°ã䜿çšããè¿ãããåã§ã³ã³ã¹ãã©ã¯ã¿ãŒå
ã®åãåç
§ããŸã
(_ -> _(n))
(_ :> _(n))
ã¯ã
_(n)
ã ãã§ãªããåãå
¥ããããã¿ã€ãã§ãã ããšãã°ãé·ã
n
ãã¯ãã«ã®ã¿ã€ãïŒ
val VecA = "Vec(A)" :: Nat ->: Type val n = "n" :: Nat val VecAInd = ("nil" ::: (VecA -> VecA(zero) )) |: {"cons" ::: n ~>>: (A ->>: (VecA :> VecA(n) ) -->>: (VecA -> VecA(succ(n)) ))} =:: VecA val vnil :: vcons :: HNil = VecAInd.intros
å¥ã®æçšãªäŸååã䜿çšãããšãå¥ã®èªç¶æ°ãè¶
ããªãèªç¶æ°ã®æŠå¿µã圢åŒåã§ããŸãã
val Fin = "Fin" :: Nat ->: Type val FinInd = {"FZ" ::: n ~>>: (Fin -> Fin(succ(n)) )} |: {"FS" ::: n ~>>: ((Fin :> Fin(n) ) -->>: (Fin -> Fin(succ(n)) ))} =:: Fin val fz :: fs :: HNil = FinInd.intros
å®éã
Fin(zero)
åã®å€ãæ§ç¯ããæ¹æ³ã¯ãããŸããã
Fin(one)
åã®å€ã¯1ã€ã ãã§ã
Fin(one)
ã
val fz0 = fz(zero) !: Fin(one)
ã¿ã€ã
Fin(two)
å€ã¯æ£ç¢ºã«2ã€ãããŸãã
val fz1 = fz(one) !: Fin(two) val fs1 = fs(one)(fz0) !: Fin(two)
ã¿ã€ã
Fin(three)
å€ã¯æ£ç¢ºã«3ã€ãããŸãã
fz(two) !: Fin(three) fs(two)(fz1) !: Fin(three) fs(two)(fs1) !: Fin(three)
ãªã©
èªå°åãã¡ããªãŒ
åž°çŽçã¿ã€ãã®ãã¡ããªãŒãšã€ã³ããã¯ã¹ä»ãã®åž°çŽçã¿ã€ãã®éãã«ã€ããŠã®ããã€ãã®èšèã ããšãã°ã
List(A)
ã¯ãã¡ããªã§ããã
Vec(A)(n)
ã¯ã¿ã€ã
A
ã«é¢é£ãããã¡ããªã§ãããã€ã³ããã¯ã¹ä»ãã¿ã€ãã¯èªç¶ã€ã³ããã¯ã¹
n
ãŸãã åž°çŽçåã¯ãã³ã³ã¹ãã©ã¯ã¿ãã次ã®ãå€ã«ãåã®ãå€ã䜿çšã§ããåã§ãïŒ
Nat
ã
List
ãªã©ã®åãšåæ§ïŒã åºå®
A
Vec(A)(n)
ã¯èªå°åã§ãããåºå®
n
å Žåã¯ããã§ã¯ãããŸããã çŸåšãProvingGroundã«ã¯åž°çŽçã¿ã€ãã®ãã¡ããªãŒã¯ãããŸããã ããšãã°ãã¿ã€ã
List(A)
åž°çŽçå®çŸ©ãæã€ããšã¯äžå¯èœã§ãããã¿ã€ã
List(B)
ã
List(Nat)
ã
List(Bool)
ã
List(List(A))
ãªã©ã®åž°çŽçå®çŸ©ãç°¡åã«ååŸã§ããŸãã ãã ããã€ã³ããã¯ã¹ä»ãã¿ã€ãã䜿çšããŠãã¡ããªããšãã¥ã¬ãŒãã§ããŸãã
val List = "List" :: Type ->: Type val ListInd = {"nil" ::: A ~>>: (List -> List(A) )} |: {"cons" ::: A ~>>: (A ->>: (List :> List(A) ) -->>: (List -> List(A) ))} =:: List val nil :: cons :: HNil = ListInd.intros cons(Nat)(zero)(cons(Nat)(one)(cons(Nat)(two)(nil(Nat)))) !: List(Nat)
ãããŠ
val Vec = "Vec" :: Type ->: Nat ->: Type val VecInd = {"nil" ::: A ~>>: (Vec -> Vec(A)(zero) )} |: {"cons" ::: A ~>>: n ~>>: (A ->>: (Vec :> Vec(A)(n) ) -->>: (Vec -> Vec(A)(succ(n)) ))} =:: Vec val vnil :: vcons :: HNil = VecInd.intros vcons(Bool)(two)(tru)(vcons(Bool)(one)(fls)(vcons(Bool)(zero)(tru)(vnil(Bool)))) !: Vec(Bool)(succ(two))
ç°çš®ãªã¹ãïŒ
HList
ïŒãå®çŸ©ããããšãã§ããŸãïŒ
val HLst = "HList" :: Type ->: Type val HLstInd = {"nil" ::: A ~>>: (HLst -> HLst(A) )} |: {"cons" ::: A ~>>: (A ->>: (B ~>>: ((HLst :> HLst(B) ) -->>: (HLst -> HLst(A) ))))} =:: HLst val hnil :: hcons :: HNil = HLstInd.intros
HList
ã§ãProvingGroundã©ã€ãã©ãªã«ç¬èªã®
HList
ãå®è£
ããŸãããããã¯Shapelessã®äžã«èšè¿°ãããŠãããã¡ã€ã³ã®æ§ç¯èŠçŽ ã¯
HList
ã§ãã
代æ°ããŒã¿å
ã©ã€ãã©ãªã¯ãäžè¬åããã代æ°ããŒã¿åïŒ
GADT ïŒããšãã¥ã¬ãŒãã§ããŸãã Haskellã³ãŒã
{-# Language GADTs #-} data Expr a where ELit :: a -> Expr a ESucc :: Expr Int -> Expr Int EIsZero :: Expr Int -> Expr Bool EIf :: Expr Bool -> Expr a -> Expr a -> Expr a
ãããŠããããªå²©ã®äž
sealed trait Expr[A] case class ELit[A](lit: A) extends Expr[A] case class ESucc(num: Expr[Int]) extends Expr[Int] case class EIsZero(num: Expr[Int]) extends Expr[Boolean] case class EIf[A](cond: Expr[Boolean], thenExpr: Expr[A], elseExpr: Expr[A]) extends Expr[A]
ãšããŠProvingGroundã«èšé²ãããŸã
val Expr = "Expr" :: Type ->: Type val ExprInd = {"ELit" ::: A ~>>: (A ->>: (Expr -> Expr(A) ))} |: {"ESucc" ::: Expr(Nat) ->>: (Expr -> Expr(Nat) )} |: {"EIsZero" ::: Expr(Nat) ->>: (Expr -> Expr(Bool) )} |: {"EIf" ::: A ~>>: (Expr(Bool) ->>: Expr(A) ->>: Expr(A) ->>: (Expr -> Expr(A) ))} =:: Expr val eLit :: eSucc :: eIsZero :: eIf :: HNil = ExprInd.intros
åã¯ã©ã¹
ã©ã€ãã©ãªã§
åã¯ã©ã¹ããšãã¥ã¬ãŒãããããšãã§ããŸãã ããšãã°ã
ãã¡ã³ã¯ã¿ãŒ ïŒ
val A = "A" :: Type val B = "B" :: Type val C = "C" :: Type val Functor = "Functor" :: (Type ->: Type) ->: Type val F = "F(_ : U_0)" :: Type ->: Type val Fmap = A ~>: (B ~>: ((A ->: B) ->: (F(A) ->: F(B) ))) val FunctorInd = {"functor" ::: F ~>>: (Fmap ->>: (Functor -> Functor(F) ))} =:: Functor val functor :: HNil = FunctorInd.intros
ããšãã°ããªã¹ãããã¡ã³ã¯ã¿ãŒã®ã€ã³ã¹ã¿ã³ã¹ãšããŠå®£èšã§ããŸãã
val as = "as" :: List(A) val indList_map = ListInd.induc(A :~> (as :-> (B ~>: ((A ->: B) ->: List(B) ))))
ã¿ã€ãã¯ã©ã¹ã«æ³åŸãè¿œå ã§ããŸãã
val fmap = "fmap" :: A ~>: (B ~>: ((A ->: B) ->: (F(A) ->: F(B) ))) val Fmap_id = A ~>: ( fmap(A)(A)(id(A)) =:= id(F(A)) ) val f = "f" :: A ->: B val g = "g" :: B ->: C val compose = A :~> (B :~> (C :~> (f :-> (g :-> (a :-> g(f(a)) ))))) !: A ~>: (B ~>: (C ~>: ((A ->: B) ->: ((B ->: C) ->: (A ->: C))))) val Fmap_compose = A ~>: (B ~>: (C ~>: (f ~>: (g ~>: ( fmap(A)(C)(compose(A)(B)(C)(f)(g)) =:= compose(F(A))(F(B))(F(C))(fmap(A)(B)(f))(fmap(B)(C)(g)) ))))) val FunctorInd = {"functor" ::: F ~>>: (fmap ~>>: (Fmap_id ->>: (Fmap_compose ->>: (Functor -> Functor(F) ))))} =:: Functor val functor :: HNil = FunctorInd.intros
å¹³çã¿ã€ã
ã©ã€ãã©ãªã«ã¯ãçµã¿èŸŒã¿ã®ã·ã°ãåïŒäŸåãã¢ã®åïŒãpiåïŒäŸåé¢æ°ã®åãäžã§æ¢ã«èŠãïŒãIDåãæ¢ã«ãããŸãã
mkPair(a, b) !: Sgma(a !: A, Ba(a)) one.refl !: (one =:= one) one.refl !: IdentityTyp(Nat, one, one) two.refl !: (two =:= two) (one =:= two) !: Type
ãã ããããšãã°åã®å¹³çãªã©ãç¬èªã«å®çŸ©ã§ããŸãã
val Id = "Id" :: A ~>: (A ->: A ->: Type) val IdInd = ("refl" ::: A ~>>: a ~>>: (Id -> Id(A)(a)(a) )) =:: Id val refl :: HNil = IdInd.intros refl(Nat)(two) !: Id(Nat)(two)(two)
å¹³çã¿ã€ãã¯ã
ã«ãªãŒã»ãã¯ãŒãéä¿¡ã«é¢ããäŒè©±ãå§ãŸããšãã«èªç¶ã«çºçããŸãã äžæ¹ã§ã¯ã
A ->: B
ã¯
A
ãã
B
ãžã®é¢æ°ã§ãããä»æ¹ã§ã¯ããfromã¹ããŒãã¡ã³ã
A
ã¯
B
ç¶ãããšããè«çåŒã§ãã ãããŠãäžæ¹ã§ã
(A ->: B) ->: A ->: B
ã¯ãå
¥åé¢æ°
A ->: B
ããã³ã¿ã€ã
A
å€ãåãåããããã«é©çšããããã®é¢æ°ãè¿ãé«éé¢æ°ã®ã¿ã€ãã§ããå€ãã€ãŸã ã¿ã€ã
B
å€
B
äžæ¹ãããã¯ãæ³åããã³ã¹ããžãã¯ã®æšè«èŠåã§ããã
A
ã
A
ããç¶ãã
A
ãçã§ããå Žåã
B
ã¯çã§ããã ãã®èŠ³ç¹ãããã¿ã€ãã¯ã¹ããŒãã¡ã³ãã§ãããã¿ã€ãå€ã¯ãããã®ã¹ããŒãã¡ã³ãã®èšŒæ ã§ãã ãããŠã察å¿ããã¿ã€ããå
¥åãããŠããå Žåãã€ãŸã ãã®ã¿ã€ãã®å€ããããŸãã è«çãandãã¯åã®ç©ã«ãè«çãorãã¯åã®åèšã«ãè«çãnotãã¯å
A ->: Zero
ã«å¯Ÿå¿ããŸãã 空ã®åã«æ©èœããŸãã ãããã£ãŠãåçè«ã«ã¯è«çããããŸãã çå®ã§ã¯ãªããè«çã§ã¯ãªãããããã
çŽèŠ³äž»çŸ©çãŸãã¯å»ºèšçãããªã㡠第äžã®æé€ã®æ³åã®ãªãè«çã å®éãäžè¬çã«èšãã°ã
PlusTyp(A, A ->: Zero)
åã®å€ãæ§ç¯ããããšã¯ã§ããŸãã
PlusTyp(A, A ->: Zero)
ïŒ
A
ã蚌æã§ããªãã£ãå Žåãããã¯
PlusTyp(A, A ->: Zero)
ã蚌æã§ãããšããæå³ã§ã¯ãããŸããïŒã èå³æ·±ãããšã«ã3çªç®ã®æé€æ³ã®åŠå®ã¯çå®ã§ãã
val g = "g" :: PlusTyp(A, A ->: Zero) ->: Zero val g1 = a :-> g(PlusTyp(A, A ->: Zero).incl1(a)) !: A ->: Zero g :-> g(PlusTyp(A, A ->: Zero).incl2(g1)) !: (PlusTyp(A, A ->: Zero) ->: Zero) ->: Zero
ã¿ã€ããã¹ããŒãã¡ã³ãã§ãããã¿ã€ãã®å€ã蚌æã§ããå Žåã2ã€ã®çšèª
a1 =:= a2
ã®ç䟡æ§ã¯ã¹ããŒãã¡ã³ãã§ãããããã¿ã€ããæå³ããŸãã ã¿ã€ããäŸåããŠããã®ã¯ã ã¿ã€ã
A
å€
a1, a2
äŸåããŸã
A
a1, a2
ç°ãªãå Žåããã®ã¿ã€ãã®å€ãæ§ç¯ããæ¹æ³ã¯ãªãã¯ãã§ãã ã¹ããŒãã¡ã³ãã¯åœã§ãã ããããåãå Žåãå察ã«ãã¹ããŒãã¡ã³ããtrueã§ãããããå€ãæ§ç¯ããæ¹æ³ãããã¯ãã§ãããã®ãããèªå°åã«ã¯ã³ã³ã¹ãã©ã¯ã¿ãŒ
refl(A)(a) !: Id(A)(a)(a)
ïŒãŸãã¯
a.refl !: (a =:= a)
çµã¿èŸŒã¿ã®ç䟡ã¿ã€ãã®å ŽåïŒã
äžçåŒãå«ãå®çã®èšŒæã«ãããå¥ã®æçšãªåïŒ
val LTE = "â€" :: Nat ->: Nat ->: Type val LTEInd = {"0 †_" ::: m ~>>: (LTE -> LTE(zero)(m) )} |: {"S _ †S _" ::: n ~>>: m ~>>: ((LTE :> LTE(n)(m) ) -->>: (LTE -> LTE(succ(n))(succ(m)) ))} =:: LTE val lteZero :: lteSucc :: HNil = LTEInd.intros
é«æ¬¡èªå°ã¿ã€ã
ã©ã€ãã©ãªå
ã®
ããé«ãåž°çŽçã¿ã€ãã䜿çšããããšãã§ããŸãã ããšãã°ãå
val Circle = "S^1" :: Type val base = "base" :: Circle
ãšç
val Sphere = "S^2" :: Type val base = "base" :: Sphere
ååž°ãšåž°çŽ
ïŒååž°ïŒé¢æ°ãå®çŸ©ããæ¹æ³ã«ã€ããŠèª¬æããŸãã ååž°çŽçã¿ã€ãã®ã©ã€ãã©ãªã¯ã
.induc
ã
.induc
ãã€ãŸã ååž°ïŒå¥åååž°ïŒããã³èªå°-å®æ°ããã³äŸååãžã®ãšãªãããŒã¿ãŒããããããå¿
èŠã«å¿ããŠååž°çã«ãã¿ãŒã³ãããã³ã°ãå®è¡ã§ããŸãã ããšãã°ãè«ççãªãnotããå®çŸ©ã§ããŸãã
val b = "b" :: Bool val recBB = BoolInd.rec(Bool) val not = recBB(fls)(tru)
ããã§ã¯ããµã³ãã«ãšæ¯èŒãããšä»®å®ã§ããŸãã
match { case true => false case false => true }
ãã¹ãŠãæ©èœããããšã確èªããŸãã
not(tru) == fls not(fls) == tru
è«ççãªãandããå®çŸ©ã§ããŸãã
val recBBB = BoolInd.rec(Bool ->: Bool) val and = recBBB(b :-> b)(b :-> fls)
ããã§ã¯ãæåã®åŒæ°ã®ãµã³ãã«ãšæ¯èŒãããšä»®å®ã§ããŸãã
ç§ãã¡ã¯ãã§ãã¯ããŸãïŒ
and(fls)(tru) == fls and(tru)(tru) == tru
èªç¶æ°ã®2åã決å®ã§ããŸãã
val n = "n" :: Nat val m = "m" :: Nat val recNN = NatInd.rec(Nat) val double = recNN(zero)(n :-> (m :-> succ(succ(m)) ))
ããã§ãããµã³ãã«ãšæ¯èŒãããšä»®å®ã§ããŸãã
ç§ãã¡ã¯ãã§ãã¯ããŸãïŒ
println(double(two).fansi) > succ(succ(succ(succ(0))))
èªç¶æ°ã®å ç®ãå®çŸ©ããŸãïŒ
val recNNN = NatInd.rec(Nat ->: Nat) val addn = "add(n)" :: Nat ->: Nat val add = recNNN(m :-> m)(n :-> (addn :-> (m :-> succ(addn(m)) )))
ããã§ããæåã®åŒæ°ã®ãµã³ãã«ãšæ¯èŒãããšåæ§ã«ä»®å®ã§ããŸãã
æ€èšŒïŒ
println(add(two)(three).fansi) > succ(succ(succ(succ(succ(0)))))
ãã¯ãã«ã®é£çµãå®çŸ©ããŸãã
val vn = "v_n" :: VecA(n) val vm = "v_m" :: VecA(m) val indVVV = VecAInd.induc(n :~> (vn :-> (m ~>: (VecA(m) ->: VecA(add(n)(m)) )))) val concatVn = "concat(v_n)" :: (m ~>: (VecA(m) ->: VecA(add(n)(m)) )) val vconcat = indVVV(m :~> (vm :-> vm))(n :~> (a :-> (vn :-> (concatVn :-> (m :~> (vm :-> vcons(add(n)(m))(a)(concatVn(m)(vm)) ))))))
ããã§ã¯ãååž°ã§ã¯ãªãåž°çŽæ³ã䜿çšããŸãã äŸååã®ãšãªãããŒã¿ãŒãå¿
èŠã§ã
m ~>: (VecA(m) ->: VecA(add(n)(m)))
-å®éããã®åã¯ãã¯ãã«ïŒæåã®é£çµåŒæ°ïŒã®
n
äŸåããŸããããã¯ãµã³ãã«ãšã®äžèŽæã«å解ãããŸãã
ãã¹ãïŒ
val a = "a" :: A val a1 = "a1" :: A val a2 = "a2" :: A val a3 = "a3" :: A val a4 = "a4" :: A val vect = vcons(one)(a)(vcons(zero)(a1)(vnil)) val vect1 = vcons(two)(a2)(vcons(one)(a3)(vcons(zero)(a4)(vnil))) println(vconcat(two)(vect)(three)(vect1).fansi) > cons(succ(succ(succ(succ(0)))))(a)(cons(succ(succ(succ(0))))(a1)(cons(succ(succ(0)))(a2)(cons(succ(0))(a3)(cons(0)(a4)(nil)))))
ProvingGroundã§å®çãã©ã®ããã«èšŒæããããã®äŸã瀺ããŸãã
add(n)(n) =:= double(n)
ããšã蚌æããŸãããã
val indN_naddSm_eq_S_naddm = NatInd.induc(n :-> (m ~>: ( add(n)(succ(m)) =:= succ(add(n)(m)) ))) val hyp1 = "n+Sm=S(n+m)" :: (m ~>: ( add(n)(succ(m)) =:= succ(add(n)(m)) )) val lemma = indN_naddSm_eq_S_naddm(m :~> succ(m).refl)(n :~> (hyp1 :-> (m :~> IdentityTyp.extnslty(succ)( add(n)(succ(m)) )( succ(add(n)(m)) )( hyp1(m) ) ))) !: n ~>: m ~>: ( add(n)(succ(m)) =:= succ(add(n)(m)) ) val lemma1 = IdentityTyp.extnslty(succ)( add(n)(succ(n)) )( succ(add(n)(n)) )( lemma(n)(n) ) val indN_naddn_eq_2n = NatInd.induc(n :-> ( add(n)(n) =:= double(n) )) val hyp = "n+n=2*n" :: ( add(n)(n) =:= double(n) ) val lemma2 = IdentityTyp.extnslty( m :-> succ(succ(m)) )( add(n)(n) )( double(n) )(hyp) indN_naddn_eq_2n(zero.refl)(n :~> (hyp :-> IdentityTyp.trans(Nat)( add(succ(n))(succ(n)) )( succ(succ(add(n)(n))) )( double(succ(n)) )(lemma1)(lemma2) )) !: n ~>: ( add(n)(n) =:= double(n) )
(...) |: (...) =:: ...
ãŠãåãéåžžã®åž°çŽåãšããŠå®çŸ©ããããšã¯ã§ããŸããïŒå®éã
loop
ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãéåžžã®åž°çŽåã®å Žåã®ããã«
Circle
åã®å€ãè¿ããŸããïŒã ãããã£ãŠãåž°çŽæ³ã«ããååž°ã¯æåã§æ±ºå®ããå¿
èŠããããŸãã
val recCirc = "rec_{S^1}" :: A ~>: a ~>: (a =:= a) ->: Circle ->: A val B = "B(_ : S^1)" :: Circle ->: Type val b = "b" :: B(base) val c = "c" :: Circle val indCirc = "ind_{S^1}" :: B ~>: b ~>: (( IdentityTyp.transport(B)(base)(base)(loop)(b) =:= b ) ->: c ~>: B(c) )
2ã€ã®å

comp_base
ããã³
comp_loop
ïŒ
val l = "l" :: ( IdentityTyp.transport(B)(base)(base)(loop)(b) =:= b ) val comp_base = "comp_base" :: B ~>: b ~>: l ~>: ( indCirc(B)(b)(l)(base) =:= b ) val P = "P(_ : A)" :: A ->: Type val f = "f" :: a ~>: P(a) val dep_map = "dep_map" :: A ~>: (P ~>: (f ~>: (a ~>: (a1 ~>: (( a =:= a1 ) ->: ( f(a) =:= f(a1) ))))))
ProvingGroundã§ã³ãŒããå®è¡ããæ¹æ³ã«é¢ããããã€ãã®èšèã 3ã€ã®æ¹æ³ããããŸãã
- æåã®æšå¥šäºé
-ã³ã³ãœãŒã«ããïŒ Ammonite REPLãããŒãããŠïŒã³ãã³ãã䜿çšããŠ
sbt mantle / testïŒå®è¡ããŸã ïŒ github.com/siddhartha-gadgil/ProvingGround.gitãªããžããªãè€è£œããåŸãProvingGroundãããžã§ã¯ãã®ã«ãŒããããAmmonite REPLã®èµ·åã«å€±æããå Žåã空ã®ãã£ã¬ã¯ããªProvingGround/mantle/target/web/classes/test
ïŒã
- 2çªç®ã¯ã
sbt server/run
ã³ãã³ãã䜿çšããŠããããã©ãŠã¶ãŒã§httpïŒ// localhostïŒ8080ãéããŸã ã
- 3çªç®ã¯IDEããã®ãã®ã§ãã IntelliJ Idea 2017.1.3ã§ã¯ãbuild.sbtã®å€æŽåŸã«ãããžã§ã¯ããã€ã³ããŒããããå ŽåããããŸãããã³ãŒããèµ·åããªãå ŽåããããŸãã 解決çã¯ããããžã§ã¯ãå
šäœã§ã¯ãªãã
ProvingGround/core
ãµããããžã§ã¯ãã®ã¿ãIdeaã«ã€ã³ããŒãããããšã§ãã ãããè¡ãã«ã¯ã æ°ããbuild.sbtã ProvingGround/core/build.sbt
ãŸãã
ã€ã³ããŒãã®ãªã¹ãïŒ
import provingground._ import HoTT._ import TLImplicits._ import shapeless._
ãã®ãããã¯ïŒåçè«ããã¢ãããŒåçè«ãäŸååãåã¬ãã«èšç®ãå®çã®èªå蚌æïŒã«èå³ããã人ã¯
ãç§ã®ã³ãŒã¹ãžããããã 圌ã¯å
¥éã§ãã HoTTã«ããã°ãããã¯ããããåºè«ã§ã¯ãªããåºè«ãžã®åºè«ã§ãããä»ã®åéã§ã¯ãåºè«ã®ã¬ãã«ã«éããŠãããšæããŸãã ãæž
èŽããããšãããããŸããã