因此,我正在尝试以最终的无标签样式创建系统omega。 我已经成功地对系统f进行了编码,如以下代码所示(还提供了一些示例)(此外,请忽略以下事实:推理不起作用,并且示例非常难看,我将在另一个问题中对它们进行询问):>
module F
%access public export
interface F (ty : Type) (val : ty -> Type) where
double : ty
mkDouble : Double -> val double
plus : val double -> val double -> val double
bool : ty
mkBool : Bool -> val bool
useBool : val bool -> val x -> val x -> val x
forall : (ty -> ty) -> ty
mkForall : (tf : ty -> ty) -> ((x:ty) -> val (tf x)) -> val (forall tf)
useForall : val (forall tf) -> (x:ty) -> val (tf x)
arr : ty -> ty -> ty
mkArr : (val x -> val y) -> val (arr x y)
useArr : val (arr x y) -> val x -> val y
[FID] F Type (\x => x) where
double = Double
mkDouble x = x
plus x y = x + y
bool = Bool
mkBool x = x
useBool x y z = if x then y else z
forall f = (x:Type) -> f x
mkForall tf f = f
useForall f x = f x
arr x y = x -> y
mkArr f = f
useArr f x = f x
fIdTy : {f : F ty val} -> ty
fIdTy {f=f} = forall @{f} $ \x => arr @{f} x x
fId : {f : F ty val} -> val (fIdTy {f=f})
fId {f=f} = mkForall @{f} (\x => arr @{f} x x) (\t => mkArr @{f} id)
fIdId : {f : F ty val} -> val (fIdTy {f=f})
fIdId {f=f} = useArr @{f} (useForall @{f} fId fIdTy) fId
useIdId : (x : Type) -> x -> x
useIdId = fIdId {f=FID}
compose : {f:F ty val} -> val (arr @{f} y z) -> val (arr @{f} x y) -> val (arr @{f} x z)
compose {f=f} yz xy = mkArr @{f} $ \x => useArr @{f} yz (useArr @{f} xy x)
composeFull : {f:F ty val} -> val (arr @{f} (arr @{f} y z) (arr @{f} (arr @{f} x y) (arr @{f} x z)))
composeFull {f=f} = mkArr @{f} $ \yz => mkArr @{f} $ \xy => compose yz xy
-- Since currying/uncurrying is only manual typing, as we shown how to convert from arr to ->, we will choose the most convient form freely.
但是我在做欧米茄时遇到了麻烦。
import F
%default total
-- look like the core calculus isnt very extensible.
-- neverthless, ftg allow us to reuse definition, so we will stick with it.
interface F (ty soty) val => FO (so:Type) (ty:so -> Type) (soty:so) (val:ty soty -> Type) where
tyArr : so -> so -> so
mkTyArr : (ty x -> ty y) -> ty (tyArr x y)
useTyArr : ty (tyArr x y) -> ty x -> ty y
forall : (s:so) -> (ty s -> ty soty) -> ty soty
mkForall : (s:so) -> (tf:ty s -> ty soty) -> ((x:ty s) -> val (tf x)) -> val (forall s tf)
useForall : val (forall s tf) -> (x:ty s) -> val (tf x)
getF : F (ty soty) val
[FOID] FO Type (\x => x) Type (\x => x) using FID where
tyArr x y = x -> y
mkTyArr f = f
useTyArr f x = f x
forall s f = (x:s) -> f x
mkForall s tf f = f
useForall f x = f x
getF = FID
-- note that we still cant has a single leb - it require type in type
leb : {fo : FO so ty soty val} -> ty s -> ty s -> ty soty
leb {fo=fo} {s=s} {soty=soty} x y = forall @{fo} (tyArr @{fo} s soty) (\f => arr @{getF @{fo}} (useTyArr @{fo} f x) (useTyArr @{fo} f y))
refl : {fo:FO so ty soty val} -> (x:ty s) -> val (leb {fo=fo} x x)
refl {s=s} {soty=soty} {fo=fo} x =
mkForall @{fo}
(tyArr @{fo} s soty)
(\f => arr @{getF @{fo}} (useTyArr @{fo} f x) (useTyArr @{fo} f x))
(\x => mkArr @{getF @{fo}} (\z => z))
trans : {fo:FO so ty soty val} -> (x:ty s) -> (y:ty s) -> (z:ty s) -> val (arr @{getF @{fo}} (leb {fo=fo} x y) (arr @{getF @{fo}} (leb {fo=fo} y z) (leb {fo=fo} x z)))
trans {s=s} {soty=soty} {fo=fo} tx ty tz =
mkArr @{getF @{fo}} {x=leb {fo=fo} tx ty} $ \xy => mkArr @{getF @{fo}} {x=leb {fo=fo} ty tz} {y=leb {fo=fo} tx tz} $ \yz =>
mkForall @{fo} _ _ $ \tf =>
compose {f=getF @{fo}}
(useForall @{fo} yz tf)
(useForall @{fo} xy tf)
symm : {fo:FO so ty soty val} -> (tx:ty s) -> (ty:ty s) -> val (leb {fo=fo} tx ty) -> val (leb {fo=fo} ty tx)
symm {s=s} {soty=soty} {fo=fo} tx ty xy = ?z $
useForall @{fo} {s=tyArr @{fo} s soty} {tf=\f => arr @{getF @{fo}} (useTyArr @{fo} f tx) (useTyArr @{fo} f ty)} xy
-- what is ?z ? the thing is, I cant write it out, because the current setup wont reduce mkTyArr and useTyArr.
所以我的问题是,如何解决?好像我可以在lambda类型上显式添加beta相等性(如Idris Eq),并让用户使用它来重写beta缩减。
但是,我希望它可以自动完成。我有什么选择?