流函子定律的证明
Proof of stream's functor laws
我一直在写类似于 Stream 的东西。我能够证明每个函子定律,但我想不出一种方法来证明它是完整的:
module Stream
import Classes.Verified
%default total
codata MyStream a = MkStream a (MyStream a)
mapStream : (a -> b) -> MyStream a -> MyStream b
mapStream f (MkStream a s) = MkStream (f a) (mapStream f s)
streamFunctorComposition : (s : MyStream a) -> (f : a -> b) -> (g : b -> c) -> mapStream (\x => g (f x)) s = mapStream g (mapStream f s)
streamFunctorComposition (MkStream x y) f g =
let inductiveHypothesis = streamFunctorComposition y f g
in ?streamFunctorCompositionStepCase
---------- Proofs ----------
streamFunctorCompositionStepCase = proof
intros
rewrite inductiveHypothesis
trivial
给出:
*Stream> :total streamFunctorComposition
Stream.streamFunctorComposition is possibly not total due to recursive path:
Stream.streamFunctorComposition, Stream.streamFunctorComposition
是否有技巧可以通过余数据证明函子定律也通过了完整性检查器?
我在 IRC 上从 Daniel Peebles (copumpkin) who explained that being able to use propositional equality over codata is just generally not something usually permitted. He pointed out that it's possible to define a custom equivalence relation, like how Agda defines ones for Data.Stream:
得到了一些帮助
data _≈_ {A} : Stream A → Stream A → Set where
_∷_ : ∀ {x y xs ys}
(x≡ : x ≡ y) (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → x ∷ xs ≈ y ∷ ys
我能够将这个定义直接翻译成 Idris:
module MyStream
%default total
codata MyStream a = MkStream a (MyStream a)
infixl 9 =#=
data (=#=) : MyStream a -> MyStream a -> Type where
(::) : a = b -> Inf (as =#= bs) -> MkStream a as =#= MkStream b bs
mapStream : (a -> b) -> MyStream a -> MyStream b
mapStream f (MkStream a s) = MkStream (f a) (mapStream f s)
streamFunctorComposition : (s : MyStream a) -> (f : a -> b) -> (g : b -> c) -> mapStream (\x => g (f x)) s =#= mapStream g (mapStream f s)
streamFunctorComposition (MkStream x y) f g =
Refl :: streamFunctorComposition y f g
这很容易通过了完整性检查器,因为我们现在只是在做简单的共同归纳。
这个事实有点令人失望,因为这似乎意味着我们无法为我们的流类型定义 VerifiedFunctor
。
Daniel 还指出,观察类型理论 确实 允许余数据上的命题相等,这值得研究。
我一直在写类似于 Stream 的东西。我能够证明每个函子定律,但我想不出一种方法来证明它是完整的:
module Stream
import Classes.Verified
%default total
codata MyStream a = MkStream a (MyStream a)
mapStream : (a -> b) -> MyStream a -> MyStream b
mapStream f (MkStream a s) = MkStream (f a) (mapStream f s)
streamFunctorComposition : (s : MyStream a) -> (f : a -> b) -> (g : b -> c) -> mapStream (\x => g (f x)) s = mapStream g (mapStream f s)
streamFunctorComposition (MkStream x y) f g =
let inductiveHypothesis = streamFunctorComposition y f g
in ?streamFunctorCompositionStepCase
---------- Proofs ----------
streamFunctorCompositionStepCase = proof
intros
rewrite inductiveHypothesis
trivial
给出:
*Stream> :total streamFunctorComposition
Stream.streamFunctorComposition is possibly not total due to recursive path:
Stream.streamFunctorComposition, Stream.streamFunctorComposition
是否有技巧可以通过余数据证明函子定律也通过了完整性检查器?
我在 IRC 上从 Daniel Peebles (copumpkin) who explained that being able to use propositional equality over codata is just generally not something usually permitted. He pointed out that it's possible to define a custom equivalence relation, like how Agda defines ones for Data.Stream:
得到了一些帮助data _≈_ {A} : Stream A → Stream A → Set where
_∷_ : ∀ {x y xs ys}
(x≡ : x ≡ y) (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → x ∷ xs ≈ y ∷ ys
我能够将这个定义直接翻译成 Idris:
module MyStream
%default total
codata MyStream a = MkStream a (MyStream a)
infixl 9 =#=
data (=#=) : MyStream a -> MyStream a -> Type where
(::) : a = b -> Inf (as =#= bs) -> MkStream a as =#= MkStream b bs
mapStream : (a -> b) -> MyStream a -> MyStream b
mapStream f (MkStream a s) = MkStream (f a) (mapStream f s)
streamFunctorComposition : (s : MyStream a) -> (f : a -> b) -> (g : b -> c) -> mapStream (\x => g (f x)) s =#= mapStream g (mapStream f s)
streamFunctorComposition (MkStream x y) f g =
Refl :: streamFunctorComposition y f g
这很容易通过了完整性检查器,因为我们现在只是在做简单的共同归纳。
这个事实有点令人失望,因为这似乎意味着我们无法为我们的流类型定义 VerifiedFunctor
。
Daniel 还指出,观察类型理论 确实 允许余数据上的命题相等,这值得研究。