簡體   English   中英

了解關於 Agda 中 FSA 和常規語言的簡單證明的遞歸調用失敗

[英]Understanding failures of recursive calls on simple proof about FSA and regular languages in Agda

我試圖證明 Agda 中的簡單 FSA 只接受以零結尾的字符串——這是 Sipser 書中的第一個示例。 我沒有將 evalFSA 實現為謂詞,而是將其實現為 function,並且對這是正確還是錯誤的選擇感到困惑,因為我現在無法證明關於機器和語言的健全性和完整性結果,以及這個實現細節是否是我遇到困難的原因。

一旦我在下面的 x 上進行模式匹配,它就會突出顯示下面的藍色線。 這是什么意思,為什么要這樣做,為什么 x0 上的模式匹配會解決它?

soundM : (xs : List Σ') → evalFSA' M xs → endsIn0 xs
soundM (x ∷ []) evM = {!!} 
soundM (x0 ∷ x1 ∷ xs) evM = {!!}
-- soundM (0' ∷ []) f = tt

這是最后一個問題。 為什么我不能在 1' 的情況下應用遞歸調用? f 之間的唯一區別是機器的使用電流 state 和輸入字符串,但顯然這似乎是系統的對稱性,不應該影響我們的計算能力。

soundM' : (xs : List Σ') → evalFSA' M xs → endsIn0 xs
soundM' (0' ∷ []) evM = tt
soundM' (0' ∷ x1 ∷ xs) f = soundM' (x1 ∷ xs) f
soundM' (1' ∷ x1 ∷ xs) f = soundM' {!!} f

這是在 0' 情況下推斷的 f:

f  : modal.helper M 0' (x1 ∷ xs) M xs (δ' S₁ x1) 

同樣在 1' 的情況下:

f  : modal.helper M 1' (x1 ∷ xs) M xs (δ' S₂ x1)

我也遇到了我所說的完整性的問題

completeM : (xs : List Σ') →  endsIn0 xs → evalFSA' M xs ≡ ⊤ 
completeM (0' ∷ []) ex = refl
completeM (0' ∷ x1 ∷ xs) ex = completeM (x1 ∷ xs) ex
completeM (1' ∷ x1 ∷ xs) ex = {!!}

這是到達這里的代碼

module fsa where

open import Bool
open import Level using (_⊔_)
open import Data.Nat.Base as Nat using (ℕ; zero; suc; _<′_; _+_)
open import Data.List.Base as List using (List; []; _∷_)
-- open import Data.Product as Prod using (∃; _×_; _,_)
open import Data.Empty
open import Data.Unit
open import Relation.Binary.PropositionalEquality using (_≡_; refl; subst)
-- open import Data.Fin as Fin

record FSA : Set₁ where
  field
    Q : Set
    Σ : Set
    δ : Q → Σ → Q
    q₀ : Q
    F : Q → Set

evalFSA' : (fsa : FSA) → List (FSA.Σ fsa) → Set
evalFSA' fsa [] = ⊥
evalFSA' fsa (x ∷ xs) = helper fsa (x ∷ xs) (FSA.q₀ fsa)
  where
    helper : (fsa : FSA) → List (FSA.Σ fsa) → (FSA.Q fsa) → Set
    helper fsa [] q = FSA.F fsa q
    helper fsa (x ∷ xs) q = helper fsa xs ((FSA.δ fsa) q x)

data Q' : Set where
  S₁ : Q'
  S₂ : Q'

data Σ' : Set where
  0' : Σ'
  1' : Σ'

q₀' : Q'
q₀' = S₁

F' : Q' → Set
F' S₁ = ⊤
F' S₂ = ⊥

δ' : Q' → Σ' → Q'
δ' S₁ 0' = S₁
δ' S₁ 1' = S₂
δ' S₂ 0' = S₁
δ' S₂ 1' = S₂

M : FSA
FSA.Q M = Q'
FSA.Σ M = Σ'
FSA.δ M = δ'
FSA.q₀ M = q₀'
FSA.F M = F'

exF1  = evalFSA' M (0' ∷ [])
exF2  = evalFSA' M (1' ∷ (0' ∷ 0' ∷ 1' ∷ []))

-- a more general endIn that i was orignally trying to use, but likewise failed to get to work
data Dec (A : Set) : Set where
  yes : A → Dec A
  no  : (A → ⊥) → Dec A

sigDec : (x y : Σ') → Dec (x ≡ y)
sigDec 0' 0' = yes refl
sigDec 0' 1' = no (λ ())
sigDec 1' 0' = no (λ ())
sigDec 1' 1' = yes refl

endsIn : {X : Set} → ((x y : X) → Dec (x ≡ y)) → List X → X → Set
endsIn d [] x = ⊥
endsIn d (x ∷ []) x0 with (d x0 x)
... | yes refl = ⊤
... | no x1 = ⊥
endsIn d (x ∷ x1 ∷ xs) x0 = endsIn d (x1 ∷ xs) x0

_endsIn'_ : List Σ' → Σ' → Set
xs endsIn' x = endsIn sigDec xs x

endsIn0 : List Σ' → Set
endsIn0 [] = ⊥
endsIn0 (0' ∷ []) = ⊤
endsIn0 (0' ∷ x ∷ xs) = endsIn0 (x ∷ xs)
endsIn0 (1' ∷ xs) = endsIn0 xs

-- testing
10endsin0 = (1' ∷ 0' ∷ []) endsIn' 0'
n10endsin0 = (1' ∷ 1' ∷ []) endsIn' 0'

您的帖子很大,包含許多元素,都可以用不同的方式發表評論。 我將一一解決它們,並解釋我為使這些元素更易於訪問而做出的選擇。 請注意,這些選擇包含在代碼中的次要元素中,主要是裝飾性的,它們不會以任何方式改變定義的語義。 我首先詳細地給你正確的代碼,然后我回答問題。


詳細的正確代碼

讓我們首先將這些導入清理到所需的最低限度:

module FSA where

open import Data.List.Base
open import Data.Empty
open import Data.Unit

然后,我保留了您對自動機記錄的定義:

record FSA : Set₁ where
  field
    Q : Set
    Σ : Set
    δ : Q → Σ → Q
    q₀ : Q
    F : Q → Set

我已經從evalFSA' function 中提取了你的helper function。 這種變化的原因是,當使用when ,function 繼承了父 function 的所有參數,這使得更難以理解進一步的目標,例如modal.helper M 0' (x1 ∷ xs) M xs (δ' S₁ x1) .

helper : (fsa : FSA) → List (FSA.Σ fsa) → (FSA.Q fsa) → Set
helper fsa [] q = FSA.F fsa q
helper fsa (x ∷ xs) q = helper fsa xs ((FSA.δ fsa) q x)

evalFSA' : (fsa : FSA) → List (FSA.Σ fsa) → Set
evalFSA' fsa [] = ⊥
evalFSA' fsa (x ∷ xs) = helper fsa (x ∷ xs) (FSA.q₀ fsa)

然后您的案例研究自動機保持不變,盡管我在不使用 copatterns 的情況下簡化了記錄實例化:

data Q' : Set where
  S₁ : Q'
  S₂ : Q'

data Σ' : Set where
  0' : Σ'
  1' : Σ'

q₀' : Q'
q₀' = S₁

F' : Q' → Set
F' S₁ = ⊤
F' S₂ = ⊥

δ' : Q' → Σ' → Q'
δ' S₁ 0' = S₁
δ' S₁ 1' = S₂
δ' S₂ 0' = S₁
δ' S₂ 1' = S₂

M : FSA
M = record { Q = Q' ; Σ = Σ' ; δ = δ' ; q₀ = q₀' ; F = F' }

我還簡化了您的謂詞endsWith0如下:

endsWith0 : List Σ' → Set
endsWith0 [] = ⊥
endsWith0 (0' ∷ []) = ⊤
endsWith0 (_ ∷ xs) = endsWith0 xs

從這一點開始, soundMcompleteM被證明如下(我將它們的簽名同質化了):

soundM : ∀ xs → evalFSA' M xs → endsWith0 xs
soundM (0' ∷ []) evM = evM
soundM (0' ∷ x₁ ∷ xs) evM = soundM (x₁ ∷ xs) evM
soundM (1' ∷ 0' ∷ xs) evM = soundM (0' ∷ xs) evM
soundM (1' ∷ 1' ∷ xs) evM = soundM (1' ∷ xs) evM

completeM : ∀ xs → endsWith0 xs → evalFSA' M xs
completeM (0' ∷ []) ex = ex
completeM (0' ∷ x₁ ∷ xs) = completeM (x₁ ∷ xs)
completeM (1' ∷ 0' ∷ xs) = completeM (0' ∷ xs)
completeM (1' ∷ 1' ∷ xs) = completeM (1' ∷ xs)

非證明相關問題的答案

  1. 關於謂詞與函數返回類型,您問:

我沒有將 evalFSA 實現為謂詞,而是將其實現為 function,並且對這是正確還是錯誤的選擇感到困惑

這個問題沒有很好的答案。 這兩種想法都是可能的,並且經常在本網站上就其他問題進行辯論。 我個人總是盡可能使用謂詞,但其他人有 arguments 支持返回的函數。 而且,正如您所注意到的,可以使用您的實現來證明您想要什么。

  1. 關於奇怪的突出顯示,你問:

它突出顯示下面的藍色線。 這是什么意思

據我所知,這是一個錯誤。 最近我也開始偶爾出現類似的一些奇怪的顏色,但它們顯然沒有任何意義。


回答您的證明相關問題

您問了以下問題:

為什么我不能在 1' 的情況下應用遞歸調用? f 之間的唯一區別是機器的使用電流 state 和輸入字符串,但顯然這似乎是系統的對稱性,不應該影響我們的計算能力

回答這個問題實際上很簡單,但是這個答案在您的實現中有些隱藏,因為您將helper的定義嵌入到evalFSA'的定義中,我按照解釋進行了更改。

讓我們在證明soundM時考慮以下代碼:

soundM : (xs : List Σ') → evalFSA' M xs → endsWith0 xs
soundM (0' ∷ []) evM = evM
soundM (0' ∷ x ∷ xs) evM = soundM (x ∷ xs) {!evM!}
soundM (1' ∷ x ∷ xs) evM = soundM (x ∷ xs) {!evM!}

當詢問 Agda 的目標是什么以及第一個目標中當前元素的類型時,它會回答:

Goal: helper M xs (δ' q₀' x)
Have: helper M xs (δ' S₁ x)

由於您已將q₀'定義如下:

q₀' : Q'
q₀' = S₁

Agda 知道q₀'在定義上等於S₁ ,這意味着當前術語實際上與目標具有相同的類型,這就是它被接受的原因。

然而,在另一個洞中,向 Agda 詢問相同的信息給出了:

Goal: helper M xs (δ' q₀' x)
Have: helper M xs (δ' S₂ x)

在這種情況下, q₀'定義上不等於S₂ (實際上也不等於),這意味着這些類型不相等,並且不可能立即得出結論。

如我的代碼所示,在x上進行模式匹配的額外時間允許 agda 進一步減少允許我們得出結論的目標。

類似的推理用於提供completeM的證明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM