簡體   English   中英

在Coq中制作和比較集合

[英]Making and comparing Sets in Coq

我無法理解是否有可能證明兩套(在這種情況下是常規語言)是相同的,因此是可以互換的。 根據我的理解,即使它們在建設性上不相等,集合也可以是等價的。

常規語言是一組字符串,但我不知道怎么說r1 = r2這樣就可以在證明中使用像對稱這樣的東西。

這是我的RegularLanguage聲明:

Inductive RegularLanguage (A : Set) : Set :=
  | EmptyLang : RegularLanguage A
  | EmptyStr : RegularLanguage A
  | Unit : A -> RegularLanguage A
  | Union :
    RegularLanguage A
    -> RegularLanguage A
    -> RegularLanguage A
  | Concat :
    RegularLanguage A
    -> RegularLanguage A
    -> RegularLanguage A
  | KleeneStar : RegularLanguage A -> RegularLanguage A
.

即使我說類型是Set,但據我所知,這並不會創建一組字符串。 我是否需要一些RegularLanguage -> Set of strings類型的RegularLanguage -> Set of strings

感謝您的幫助。

關於一些Coq概念存在一些誤解,我將試圖澄清。

首先,在Coq中,你不應該Set視為傳統數學中我們稱之為“set”的東西。 相反,您應該將其視為一種類型 Coq也有Type ,但出於本文的目的,您可以SetType視為可互換。 為了避免混淆,從現在開始,我將使用“set”來指代傳統數學中通常的set概念,並使用“type”來指代Coq中SetType元素。

那么,集合和類型之間究竟有什么區別? 那么,在正常的數學中,問問自己是否有任何東西任何給定集合的成員是有道理的。 因此,如果我們要在正常數學中發展正則表達式理論,並且每個正則表達式都被視為一個集合,那么0 \\in EmptyLang提出諸如0 \\in EmptyLang ,因為即使0是自然數,它可能是任何先驗集合的元素。 作為一個不太習慣的例子,空字符串既是完整語言的成員(即包含所有字符串的成員),也是任何基本語言的Kleene閉包。

另一方面,在Coq中,語言的每個有效元素只有一種類型。 例如,空字符串具有某些A類型list A A ,其寫為[] : list A 如果我們嘗試使用“has type”語法詢問[]是否屬於某種常規語言,則會出現錯誤; 嘗試輸入例如

Check ([] : EmptyLang). 

兩個集合和類型都可以看作是元素的集合,但是類型在某種意義上更具限制性:例如,一個可以采用兩個集合的交集,但是沒有辦法采用兩種類型的交集。

第二,當你寫作

Inductive RegularLanguage (A : Set) : Set := (* ... *)

並不意味着您列出的標題下的元素定義設置,也不類型。 這意味着,對於每個類型A(A : Set)部分),您要定義一個新的類型,注明RegularLanguage ARegularLanguage (A : Set) : Set part),其元素由列表自由生成施工人員給出的。 因此,我們有

EmptyLang : RegularLanguage nat

RegularLanguage nat : Set

但我們沒有

EmptyLang : Set

(再次,您可以嘗試將所有上述判斷鍵入Coq,以查看哪些被接受,哪些不被接受)。

“自由生成”特別意味着你列出的構造函數是單射的不相交的 正如之前提到的那樣,特別是Union l1 l2 = Union l2 l1的情況並非如此; 事實上,你通常可以證明Union l1 l2 <> Union l2 l1 問題在於,您在Coq(您無法更改)中的歸納定義類型與您對常規語言的平等概念的相同概念之間存在不匹配。

雖然有幾種解決方法,但我認為最簡單的方法是使用setoid重寫功能。 這將涉及首先定義函數或謂詞(例如,作為larsr建議,布爾函數regexp_match : RegularLanguage A -> list A -> bool )以確定常規語言何時包含某些字符串。 然后,您可以在語言上定義等價關系:

Definition regexp_equiv A (l1 l2 : RegularLanguage A) : Prop :=
  forall s, regexp_match l1 s = regexp_match l2 s.

並使用setoid rewrite來重寫這種等價關系。 然而,有一個小警告,即你只能在與這種等價關系兼容的上下文中用等價關系重寫,並且你需要明確地證明lemmas這樣做。 您可以在參考手冊中找到更多詳細信息。

如果它們是由不同的構造函數構造的,則集合中的兩個不同元素RegularLanguage A不相等。 考慮L1 = ( a | b )L2 = ( b | a) 這里L1 <> L2因為構造函數的參數不同。

在你的符號中,L1可能是Union nat (Unit nat 1) (Unit nat 2)) ,L2是Union nat (Unit nat 2) (Unit nat 1))

相反,你想說有一個函數regexp_match : A -> RegularLanguage A -> list A -> bool匹配給定語言的字符串。 您必須實現此功能。

如果匹配並拒絕相同的字符串,則兩個正則表達式相等。 例如,對於L1L2

Lemma L1_eq_L2 : forall S, regexp_match L1 S = regexp_match L2 S.

如果您可以證明這一點,那么您可以使用它來將regexp_match L1 S替換為regexp_match L2 S ,反之亦然。

暫無
暫無

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

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