Agda,证明类型和条款

时间:2014-12-27 12:45:56

标签: agda

在AgdaIntro中,视图部分解释:

  

.. with 不记得with-term和。之间的关联   模式。

这意味着你定义

data   False : Set where
record True  : Set where

isTrue : Bool -> Set
isTrue true  = True
isTrue false = False

infixr 30 _:all:_
data All {A : Set}(P : A -> Set) : List A -> Set where
  all[]   : All P []
  _:all:_ : forall {x xs} -> P x -> All P xs -> All P (x :: xs) 

satisfies : {A : Set} -> (A -> Bool) -> A -> Set
satisfies p x = isTrue (p x)

data Find {A : Set}(p : A -> Bool) : List A -> Set where
  found : (xs : List A)(y : A) -> satisfies p y -> (ys : List A) -> 
           Find p (xs ++ y :: ys)
  not-found : forall {xs} -> All (satisfies (not � p)) xs -> 
              Find p xs

你要证明

find1 :{A:Set}(p:A->Bool)(xs:ListA)->Find p xs 
find1 p [] = not-found all []
find1 p(x::xs) with p x
...| true  = found [] x {!!} xs
...| false = {!!}
  

洞的类型({!!})是isTrue(p x),即使我们已经   在p x上匹配并发现它是真的。

编译器不知道我们在p x上进行了模式匹配,并要求我们提供p x为真的证据!

这促使引入新类型

  

..类型A的元素类型以及它们相等的证明   在A中给出一些给定的x。

data Inspect {A : Set}(x : A) : Set where
  it : (y : A) -> x == y -> Inspect x

inspect : {A : Set}(x : A) -> Inspect x
inspect x = it x refl

使用此类型,可以编写函数find:

trueIsTrue : {x : Bool} -> x == true -> isTrue x
trueIsTrue refl = _

falseIsFalse : {x : Bool} -> x == false -> isFalse x
falseIsFalse refl = _

find : {A : Set}(p : A -> Bool)(xs : List A) -> Find p xs
find p [] = not-found all[]
find p (x :: xs) with inspect (p x)
... | it true prf = found [] x (trueIsTrue prf) xs
... | it false prf with find p xs
find p (x :: ._) | it false _   | found xs y py ys =
  found (x :: xs) y py ys
find p (x :: xs) | it false prf | not-found npxs =
  not-found (falseIsFalse prf :all: npxs)

现在,如果我想证明以下属性:

predicate : ∀ {A : Set} {p : A -> Bool } {xs : List A } -> 
            All (satisfies' p) (filter p xs)

我将遇到与find相同的问题,所以我需要在inspect上进行模式匹配才能获得见证,但是 ALSO 需要让编译器在过滤器中进行{{1 }}

如果我进行一些并行模式匹配,编译器会将它们视为独立表达式

p x == true

如何告诉编译器这两个分支是以某种方式链接的? 我应该加一个证明吗?

1 个答案:

答案 0 :(得分:3)

请勿在{{1​​}}上进行模式匹配:

p x

请注意,不推荐使用predicate {A} {p} {xs = []} = all[] predicate {A} {p} {x :: xs} with inspect (p x) predicate {A} {p} {x :: xs} | it true pf rewrite pf = {!!} predicate {A} {p} {x :: xs} | it false pf rewrite pf = {!!} 惯用法。使用inspect on steroids。您可以在标准库here中找到它。

您的代码变为

inspect

predicate : ∀ {A : Set} {p : A -> Bool } {xs : List A } -> All (satisfies p) (filter p xs) predicate {A} {p} {xs = []} = all[] predicate {A} {p} {xs = x :: xs} with p x | inspect p x predicate {A} {p} {x :: xs} | true | [ pf ] = {!!} predicate {A} {p} {x :: xs} | false | [ pf ] = {!!} 位于第一洞

pf

哪个beta减少到.Data.Unit.Core.reveal (.Data.Unit.Core.hide p x) == true 。即如果你有

p x == true

然后将test : ∀ {A : Set} {p : A -> Bool} {x} -> p x == true -> True test _ = _ 放在第一个洞并输入C-c C-d会给你test {p = p} pf