Idris中的Forall量词和复杂的布尔命题

时间:2014-12-02 14:34:45

标签: logic prefix dependent-type idris

我是依赖类型的新手,并且拥有Haskell经验,我正在慢慢学习Idris。对于一个练习,我想写一个霍夫曼编码。目前我正试图写一个证明"展平"代码树产生了前缀代码,但却被量词所困扰。

我有一个简单的归纳命题,一个列表是另一个列表的前缀:

using (xs : List a, ys : List a)
    data Prefix : List a -> List a -> Type where
        pEmpty : Prefix Nil ys
        pNext  : (x : a) -> Prefix xs ys -> Prefix (x :: xs) (x :: ys)
  1. 这是一种有效的方法吗?或者类似&#34; xs ys 的前缀,如果有 zs 那样 xs ++ < em> zs = ys &#34;会更好吗?

  2. 这是引入&#34; forall&#34;的正确方法。量词(据我所知,在Agda中它会像pNext : ∀ {x xs ys} → Prefix xs ys → Prefix (x :: xs) (y :: ys))? pNext第一个参数应该隐含吗?两种变体之间的语义差异是什么?

  3. 然后,我想为一个向量构建一个向量,其中没有元素形成另一个元素的前缀:

    data PrefVect : Vect n (List a) -> Type where
    

    空向量没有前缀:

        pvEmpty : PrefVect Nil
    

    给定一个元素x,一个向量xs,并证明xs的任何元素都不是x的前缀(反之亦然),x :: xs将保存该属性:

        pvNext  : (x : [a]) -> (xs : Vect n [a]) ->
                  All (\y => Not (Prefix x y)) xs ->
                  All (\y => Not (Prefix y x)) xs ->
                  PrefVect (x :: xs)
    

    这是一个无效的类型,我希望在处理第一个类型之后修复,但pvNext中有关于量词的类似问题:这个变体是否可以接受,或者有更好的方法来形成&#34;否定关系&#34;

    谢谢。

1 个答案:

答案 0 :(得分:3)

我认为这里唯一的问题是你在Haskell风格中使用[a]作为a列表的类型,而在Idris中它必须是{{1} }。

我的List a类型对我来说很好,尽管我将它写成:

Prefix

也就是说,data Prefix : List a -> List a -> Type where pEmpty : Prefix [] ys pNext : Prefix xs ys -> Prefix (x :: xs) (x :: ys) 可能是隐含的,您不需要x,因为Idris可以推断出usingxs的类型。这是否是正确的方法实际上取决于您打算使用ys类型的计划。它当然很容易测试列表是否是另一个列表的前缀。类似的东西:

Prefix

如果你想证明你可能会出现的否定,你需要这种类型:

testPrefix : DecEq a => (xs : List a) -> (ys : List a) -> Maybe (Prefix xs ys)
testPrefix [] ys = Just pEmpty
testPrefix (x :: xs) [] = Nothing
testPrefix (x :: xs) (y :: ys) with (decEq x y)
  testPrefix (x :: xs) (x :: ys) | (Yes Refl) = Just (pNext !(testPrefix xs ys
  testPrefix (x :: xs) (y :: ys) | (No contra) = Nothing

我将这一个留作练习:)。