Types idris中最终无标记的omega故障编码系统

Types idris中最终无标记的omega故障编码系统,types,idris,system-f,tagless-final,Types,Idris,System F,Tagless Final,所以我试着用最终的无标签风格来制作system f omega。 我已经成功地对系统f进行了编码,如下代码(还提供了一些示例)(另外,请忽略推理不起作用的事实,这些示例非常难看,我将在另一期中询问): 但是我做Fω有困难 import F %default total -- look like the core calculus isnt very extensible. -- neverthless, ftg allow us to reuse definition, so we will

所以我试着用最终的无标签风格来制作system f omega。 我已经成功地对系统f进行了编码,如下代码(还提供了一些示例)(另外,请忽略推理不起作用的事实,这些示例非常难看,我将在另一期中询问):

但是我做Fω有困难

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等式(如idriseq),并让用户使用它重写beta缩减

然而,我希望它是自动完成的。我的选择是什么

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.