在Idris中证明流函数的性质

时间:2019-04-01 19:13:17

标签: stream idris dependent-type frp

我正试图证明有关流函数和Monadic流函数[1](最终是FRP程序)的属性。

Idris对我对流函数的形式化感到满意:

module SF

import Data.Vect
import Syntax.PreorderReasoning

%default total

data SF : Type -> Type -> Type where
  SFG : (a -> (b, Inf (SF a b))) -> SF a b

steps : {n : Nat} -> SF a b -> Vect n a -> Vect n b
steps {n = Z}   (SFG s) []        = []
steps {n = S m} (SFG s) (a :: as) =
    let (b, s') = s a
        bs = steps s' as
    in (b::bs)

我可以轻松定义提升/逐点应用功能:

liftM : (a -> b) -> SF a b
liftM f = SFG $ \a => (f a, liftM f)

以及SF身份的两个变体:

identityM : SF a a
identityM = SFG $ \a => (a, identityM)

identity2 : SF a a
identity2 = liftM id

这将通过Idris的总计检查器。但是,如果我现在尝试证明identityMidentity2相等,则会遇到问题。我可以将属性声明如下:

proof1 :  (Eq b)
       => (n : Nat)
       -> (v : Vect n a)
       -> (steps identityM v) = (steps identity2 v)
proof1 Z [] = ?proof1_rhs_1
proof1 (S k) v = ?proof1_rhs_2

如果我要求输入?proof1_rhs_1的类型,idris会正确地说出steps identityM [] = steps identity2 []。但是,如果我尝试使用方程式推理来表达这一点:

proof1 Z [] = (steps {n=Z} identityM []) ={ ?someR }=
              (steps {n=Z} identity2 []) QED

然后idris不高兴:

When checking argument x to function Syntax.PreorderReasoning.Equal.qed:
        Type mismatch between
                steps identity2 [] (Inferred value)
        and
                steps identity2 [] (Given value)

        Specifically:
                Type mismatch between
                        steps identity2
                and
                        []Unification failure

有什么办法可以使这项工作成功吗?

[1] https://dl.acm.org/citation.cfm?id=2976010

1 个答案:

答案 0 :(得分:3)

这是通常的“ Idris隐式泛化使混乱的作用域规则产生的作用”:

proof1 :  (Eq b)
       => (n : Nat)
       -> (v : Vect n a)
       -> (steps identityM v) = (steps identity2 v)

表示

proof1 : {identityM : _} -> {identity2 : _} -> (...)
       -> (steps identityM v) = (steps identity2 v)

要引用先前的定义,您需要使用限定名称SF.identityMSF.identity2。您可能还有其他问题(Eq b中的b在其他类型的其他地方似乎都没有提及)。