简体   繁体   English

了解关于 Agda 中 FSA 和常规语言的简单证明的递归调用失败

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

I'm trying to prove that a simple FSA in Agda only accepts string which end in zero- this is the first example in Sipser's book.我试图证明 Agda 中的简单 FSA 只接受以零结尾的字符串——这是 Sipser 书中的第一个示例。 I didn't implement evalFSA as a predicate, but rather as function, and am confused as to whether this was the right or wrong choice, as I'm now having trouble proving the soundness and completeness results with respect to the machine and the language, and whether this implementation detail is the cause of my difficululties.我没有将 evalFSA 实现为谓词,而是将其实现为 function,并且对这是正确还是错误的选择感到困惑,因为我现在无法证明关于机器和语言的健全性和完整性结果,以及这个实现细节是否是我遇到困难的原因。

As soon as I pattern match on x below, it highlights the below line blue.一旦我在下面的 x 上进行模式匹配,它就会突出显示下面的蓝色线。 what does this mean, why is it doing it, and why does pattern matching on x0 resolve it?这是什么意思,为什么要这样做,为什么 x0 上的模式匹配会解决它?

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

and here is the final issue.这是最后一个问题。 why can't I apply the recursive call in the 1' case?为什么我不能在 1' 的情况下应用递归调用? the only difference between the f's is the use current state of the machine and the input string, but obviously this seems like a symmetry of the system that shouldn't effect our ability to compute. 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

Here is the inferred f in the 0' case:这是在 0' 情况下推断的 f:

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

And similairly in the 1' case:同样在 1' 的情况下:

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

I'm having, simultaneous issues with what I'm calling completeness as well我也遇到了我所说的完整性的问题

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 = {!!}

Here is the code to get here这是到达这里的代码

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'

Your post is very large and contains numerous elements, which all can be commented in different ways.您的帖子很大,包含许多元素,都可以用不同的方式发表评论。 I will address them one by one, and explain the choices I made to make these elements more easily accessible.我将一一解决它们,并解释我为使这些元素更易于访问而做出的选择。 Note that these choices consist in minor elements in your codes, mostly cosmetic, which do not change in any way the semantics of your definitions.请注意,这些选择包含在代码中的次要元素中,主要是装饰性的,它们不会以任何方式改变定义的语义。 I start by giving you the correct code in details, after which I answer the questions.我首先详细地给你正确的代码,然后我回答问题。


The correct code in details详细的正确代码

Let us start by cleaning up these imports to the minimum needed:让我们首先将这些导入清理到所需的最低限度:

module FSA where

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

I then kept your definition of your automaton record:然后,我保留了您对自动机记录的定义:

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

I have extracted your helper function from the evalFSA' function.我已经从evalFSA' function 中提取了你的helper function。 The reason for this change is that when using when , the function inherits all the parameters from the parent function, which makes it harder to comprehend further goals such as modal.helper M 0' (x1 ∷ xs) M xs (δ' S₁ x1) .这种变化的原因是,当使用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)

Then your case study automaton remains the same, although I simplified the record instantiation without using copatterns:然后您的案例研究自动机保持不变,尽管我在不使用 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' }

I also simplified your predicate endsWith0 as follows:我还简化了您的谓词endsWith0如下:

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

From this point on, soundM and completeM are proved as follows (I homogenized their signatures):从这一点开始, 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)

Answers to non-proof related questions非证明相关问题的答案

  1. On predicates vs functions returning types, you asked:关于谓词与函数返回类型,您问:

I didn't implement evalFSA as a predicate, but rather as function, and am confused as to whether this was the right or wrong choice我没有将 evalFSA 实现为谓词,而是将其实现为 function,并且对这是正确还是错误的选择感到困惑

There are no good answer to this question.这个问题没有很好的答案。 Both ideas are possible, and often debated on other questions on this site.这两种想法都是可能的,并且经常在本网站上就其他问题进行辩论。 I personally always use predicates when possible, but others have arguments in favor of functions returning or .我个人总是尽可能使用谓词,但其他人有 arguments 支持返回的函数。 And, as you noticed it is possible to prove what you wanted using your implementation.而且,正如您所注意到的,可以使用您的实现来证明您想要什么。

  1. On the weird highlighting, you asked:关于奇怪的突出显示,你问:

it highlights the below line blue.它突出显示下面的蓝色线。 what does this mean这是什么意思

As far as I know, this is a bug.据我所知,这是一个错误。 Some weird coloration like that started to occasionally happen to me recently as well, but they apparently do not mean anything.最近我也开始偶尔出现类似的一些奇怪的颜色,但它们显然没有任何意义。


Answer to your proof-related question回答您的证明相关问题

You asked the following question:您问了以下问题:

why can't I apply the recursive call in the 1' case?为什么我不能在 1' 的情况下应用递归调用? the only difference between the f's is the use current state of the machine and the input string, but obviously this seems like a symmetry of the system that shouldn't effect our ability to compute f 之间的唯一区别是机器的使用电流 state 和输入字符串,但显然这似乎是系统的对称性,不应该影响我们的计算能力

Answering this question is actually quite simple, but this answer was somewhat hidden in your implementation because you embedded the definition of helper inside the definition of evalFSA' , which I changed as explained.回答这个问题实际上很简单,但是这个答案在您的实现中有些隐藏,因为您将helper的定义嵌入到evalFSA'的定义中,我按照解释进行了更改。

Let us consider the following code while proving soundM :让我们在证明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!}

When asking Agda what is the goal and the type of the current element in the first goal, it answers:当询问 Agda 的目标是什么以及第一个目标中当前元素的类型时,它会回答:

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

Since you have defined q₀' as follows:由于您已将q₀'定义如下:

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

Agda know that q₀' is definitionally equal to S₁ which means the current term has actually the same type as the goal, which is why it is accepted. Agda 知道q₀'在定义上等于S₁ ,这意味着当前术语实际上与目标具有相同的类型,这就是它被接受的原因。

In the other hole however, asking Agda the same information gives:然而,在另一个洞中,向 Agda 询问相同的信息给出了:

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

In this case, q₀' is not definitionally equal to S₂ (and not equal in any way actually) which means these types are not equal, and it is not possible to conclude right away.在这种情况下, q₀'定义上不等于S₂ (实际上也不等于),这意味着这些类型不相等,并且不可能立即得出结论。

As shown in my code, pattern matching an additional time on x allows agda to further reduce the goal which allows us to conclude.如我的代码所示,在x上进行模式匹配的额外时间允许 agda 进一步减少允许我们得出结论的目标。

A similar reasoning is used to provide a proof of completeM类似的推理用于提供completeM的证明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM