有限自动机Coq的定义
我正在学习Coq,我想用它来形式化正则语言理论,特别是有限自动机。假设我有一个自动机的结构,如下所示:有限自动机Coq的定义,coq,finite-automata,language-theory,Coq,Finite Automata,Language Theory,我正在学习Coq,我想用它来形式化正则语言理论,特别是有限自动机。假设我有一个自动机的结构,如下所示: Record automata : Type := { dfa_set_states : list state; init_state : state; end_state : state; dfa_func: state -> terminal -> state; }. 其中状态为感应型,如下所示: Inductive state:Type := S. 终端类型为 Induc
Record automata : Type := {
dfa_set_states : list state;
init_state : state;
end_state : state;
dfa_func: state -> terminal -> state;
}.
其中状态为感应型,如下所示:
Inductive state:Type :=
S.
终端类型为
Inductive terminal:Type :=
a | b.
我正在尝试定义它,所以稍后我将能够概括任何常规语言的定义。现在,我想构造一个自动机来识别语言(a*b*),它是{a,b}字母表上的所有单词。有人知道如何构建某种固定点函数来运行这个单词(我把它看作是一个终端列表),并告诉我这个自动机是否重新命名了这个单词吗?任何想法/帮助都将不胜感激
提前感谢,,
Erick.因为你把自己局限于常规语言,所以这很简单:你只需要使用折叠。以下是一个示例:
Require Import Coq.Lists.List.
Import ListNotations.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Record dfa (S A : Type) := DFA {
initial_state : S;
is_final : S -> bool;
next : S -> A -> S
}.
Definition run_dfa S A (m : dfa S A) (l : list A) : bool :=
is_final m (fold_left (next m) l (initial_state m)).
这段代码与您最初的定义有点不同,因为状态和字母表组件现在是DFA的类型参数,并且我用一个谓词替换了结束状态,该谓词可以回答我们是否处于接受状态。run\u dfa
函数只是从初始状态开始迭代dfa的转换函数,然后测试最后一个状态是否为接受状态
您可以使用此基础结构来描述几乎任何常规语言。例如,这里有一个自动识别a*b*
:
Inductive ab := A | B.
Inductive ab_state : Type :=
ReadA | ReadB | Fail.
Definition ab_dfa : dfa ab_state ab := {|
initial_state := ReadA;
is_final s := match s with Fail => false | _ => true end;
next s x :=
match s, x with
| ReadB, A => Fail
| ReadA, B => ReadB
| _, _ => s
end
|}.
我们可以证明这台自动机做了我们所期望的。下面是一个定理,它接受所寻求语言的字符串:
Lemma ab_dfa_complete n m : run_dfa ab_dfa (repeat A n ++ repeat B m) = true.
Proof.
unfold run_dfa. rewrite fold_left_app.
assert (fold_left (next ab_dfa) (repeat A n) (initial_state ab_dfa) = ReadA) as ->.
{ now simpl; induction n as [| n IH]; simpl; trivial. }
destruct m as [|m]; simpl; trivial.
induction m as [|m IH]; simpl; trivial.
Qed.
我们还可以声明一个相反的说法,即它只接受该语言的字符串,而不接受其他任何内容。我漏掉了证据;这应该不难理解
Lemma ab_dfa_sound l :
run_dfa ab_dfa l = true ->
exists n m, l = repeat A n ++ repeat B m.
不幸的是,除了运行自动机之外,我们无法用这种表示法做很多事情。特别是,我们不能最小化一个自动机,测试两个自动机是否等价,等等。这些函数还需要将枚举状态和字母表类型的所有元素的列表作为参数,
S
和A
这在Coq中很难做到,因为每个函数都必须终止。您可以在和上查看一些解决方案。一种更简单的方法是,如果在函数中添加一个“fuel”参数,即允许识别器工作的字符数。那么,当燃料大于或等于单词的长度时,你应该能够证明它是有效的。你是说{a,b}字母表上所有单词的语言都是(a | b)*
?亚瑟,我现在遇到了另一个问题:你说用这个表示法,我们无法测试两个自动机是否等价,也无法最小化它们。你对我们如何表示一个自动机有什么想法吗?这样我们就可以做到了?我也期待着有一种方法将一个规则语法转换成一个有限自动机,这些函数将是有用的。