我正试图证明有关流函数和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的总计检查器。但是,如果我现在尝试证明identityM
和identity2
相等,则会遇到问题。我可以将属性声明如下:
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
有什么办法可以使这项工作成功吗?
答案 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.identityM
和SF.identity2
。您可能还有其他问题(Eq b
中的b
在其他类型的其他地方似乎都没有提及)。