[英]Agda, type of proofs and with clause
在AgdaIntro中,視圖部分解釋:
..that 與不記得有長期和圖案之間的連接。
這意味着當你定義
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(px),即使我們已經在px上匹配並發現它是真的。
編譯器不知道我們在px上進行了模式匹配,並要求我們提供px為真的證據!
這促使了一種新型的引入
..類型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)
我有同樣的問題與發現,所以我需要檢查得到見證模式匹配,但我也需要有編譯器的情況下,在過濾器上的進展px == true
!
如果我進行一些並行模式匹配,編譯器會將它們視為獨立表達式
predicate {A} {p} {xs = []} = all[]
predicate {A} {p} {xs = x :: xs} with p x
predicate {A} {p} {x :: xs} | px with inspect (p x)
predicate {A} {p} {x :: xs} | true | it true pf = {!!}
predicate {A} {p} {x :: xs} | true | it false pf = {!!}
predicate {A} {p} {x :: xs} | false | it true pf = {!!}
predicate {A} {p} {x :: xs} | false | it false pf = {!!}
如何告訴編譯器兩個分支以某種方式鏈接? 我應該加一個證明嗎?
只是不要在px
上進行模式匹配:
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
習慣用法。 使用類固醇檢查 。 您可以在此處的標准庫中找到它。
你的代碼變成了
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
在第一洞
.Data.Unit.Core.reveal (.Data.Unit.Core.hide p x) == true
哪個beta減少到px == true
。 即如果你有的話
test : ∀ {A : Set} {p : A -> Bool} {x} -> p x == true -> True
test _ = _
然后在第一個洞中放置test {p = p} pf
並輸入Cc Cd給你True
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.