学习Automata PPT的记录. 相关笔记会另开博客记录. 也可能不会开.
- PDA是等价于CFG的自动机. (关于互相转换的构造过程. )
- 只有非确定性PDA能够包含所有CFL. (确定性PDA比较弱, 而且两种生成方式的结果有区别. )
- 大部分编程语言可以通过 Deterministic PDA 描述. (满足Prefix Property?)
PDA Intuition
- 引入了一个栈
- PDA的行为由当前状态, 当前输入, 栈顶元素共同决定
对于每个动作, PDA可以
- 改变状态, 同时
- 将栈顶符号替换为任意数量的符号 (一次pop和任意次push)
形式化的, PDA可以通过七元组表示
- 一个有限状态集合
- 输入字母表
- 栈字母表
- 转移函数
- 起始状态
- 起始符号
- 有穷终止集合
对于转移函数, is a set of zero or more actions of the form
- 接受当前状态, 当前输入, 以及栈顶元素
- 返回下一个状态以及一系列栈中的元素 (类似NFA, 有多个动作可以同时进行. )
对于每一个输入 , PDA会
- 转移状态
- 将a从input 移除 (a可以是空字符)
- 将栈顶元素进行替换
用栈来存储信息: 表示
Instantaneous Descriptions (ID)
A ID is a triple (q, w, X), where:
- q is the current state
- w is the remaining input
- X is the stack contents, top at the left
类似广义的状态.
广义状态转移函数 “Goes-To” Relation
- ID I can become ID J in one move of the PDA:
- Extend Goes-To : . 任意次转移
TH 1: Given a PDA P, if , for all the string and all string , we have
类似的"反面"定理:
TH2: Given a PDA P, if , we have
注意, 这并不是TH1的直接反面. 因为 可能被用到, 与输入不同(并不完全是线性遍历)
Language of a PDA
The common way is by final state
只关心状态是否为终止态, 字符串是否读完, 对栈中的内容并不关心
Another language defined by the same PDA is by empty stack.
只关心栈中是否是空, 字符串是否读完, 对状态并不关心
Equivalence of Language Definitions
- If , then there is another PDA such that
- If , then there is another PDA such that
构造性地证明定理的正确性
Proof:
对于
对于新的PDA, 为了防止它的栈意外地空了, 添加一个守卫元素 . (原本栈空了且不在终止态时, 不应该被接收; 但是倘若不添加守卫元素, 它就会在新的N(P)中被接收. )
- 引入一个新的起始状态 和一个 “最终状态” .
- 添加转移函数为
- 添加 到 , 对于任意的
- 添加
一头一尾添加一个"转接口". 其实感觉尾巴的转接口有点怪了. 应该设置成先把所有终止态上的东西转移成 , 然后再把统一转换成空. 这样比较自然一点.
或者直接删掉e上的转换也可以.
对于
对于新的PDA, 为了捕捉栈为空的情况, 添加一个标记元素 .
- 引入一个新的起始状态 和一个终止状态 .
- 添加转移函数为
- 添加, 对于任意的
一头一尾添加一个"转接口"
Example: 构建 if-else 语法的CFL.
通过的方式构建是显然的(记录if的个数, 然后让else与之相匹配).
可以将的PDA改写成 的PDA
改写成Deterministic PDA’s
要求: 对于每个状态, 动作需要有且只有一个 (不能为空, 也不能有多个)
- 动作可以包含空字符作为输入.
- 且只有在"无路可走"的时候, 通过空字符进行移动才能被允许.
对于DPDA和 NPDA
NPDA is more powerful than DPDA
Ex:
- 考虑语言, 例如. 它只接收m个0的情况.
- 同时, 我们考虑
- 那么, 它在接收到 时, 栈一定会是空的. 此时若字符串终止, 则它将这个字符串接受.
- 这时, 如果它又接收到串 , 它应当接受整个字符串 .
- 这时, 如果它又接收到串 , 它应当拒绝整个字符串 .
- 这个时候, 因为栈已经是空的了(DPDA退化为DFA), 所以DPDA无法判断
这个证明过程好像没那么精确. 因为N(DPDA) 具有 prefix property, 所以直接可以得到反例.
假如采用final states定义呢?
此时不考虑栈的时候, DPDA退化为DFA. 假设有这样的DPDA.
对于任意回文字符串 , 我们有 , 其中 可以与输入相关, 也可以无关.
此时, 我们再次输入, 那么就会有
输入一个与不同的回文串, 就会有 , 且 不为接收态.
思路: 假设有这样的DPDA, 构造反例. "信息有限"的角度考虑.
- 由于转移是确定性的. 所以只考虑栈顶元素的情况下, 一定存在这样的情况, 此时 . 其中 为两个不同的字符串, 为同一个状态, 的栈顶元素相同.
- 此时, 若输入同一个字符串, 它们后续的转移过程都是一样的, 因为栈顶元素的状态是一致的.
- 但是, 需要被接受, 而 需要被拒绝. 这是不可能的. 产生矛盾.
所以, 两种定义下, NPDA都强于DPDA.
但是DPDA可以用于表示 . (因为此时明确给出了一个界限c. 如果没有这个界限c, 我们就只能借助非确定性的力量来"猜测")
- 当没有遇见c的时候, push
- 否则, pop
TH: If L is a regular language, there exists a DPDA P, such that
即, L(P)定义的情况下, DPDA的表达力不弱于RE (因为采用final states定义的前提下, 它是推广的DFA, 当栈始终不变时, 它退化成普通的DFA)
这个定理中, DPDA的语言通过 final states定义. 如果是通过 定义呢? 这时情况就会发生变化…
Ex: 考虑 . 它可以用RE表示. 但是不存在DPDA, 使得. (通过反证法可以证明)
采用empty stack 定义时, 若 , 则对任意, 都不属于
换言之, 满足 prefix property性质, 即不存在两个串属于L, 使得一个串是另一个串的前缀.
这么看来DPDA采用empty stack时非常弱啊…
DPDA 的L语言与N语言的关系
Theorem 6.19:
A language is for some DPDA if and only if has
the prefix property and is for some DPDA .
即, 在prefix property的前提下,
Prove:
假设对于语言 , 满足前置码的性质, 同时 . 那么构造性地给出一个 :
2. 添加一个转接头, 负责加入守卫元素, 避免栈为空时, 错误把字符串接收了. (对于不该接收的状态, 如 , 防止栈为空)
3. 对于所有 , 它们转移到 . (这一点是由前置码保证的. 前置码告诉我们在原本的P中, ) (对于应该接收的字符, 强制令栈为空)
假设对于语言 , 有一个 , 下面构造性地给出一个 , 同时证明L满足前置性(显然):
- 添加一个转接头, 负责加入守卫元素.
- 在栈为空(只剩下守卫元素)且字符串为空时, 会转移到终止状态e (将应该接收的字符串接收)
证毕.
于是我们有
且
同时, 有的 无法用 表达, 有的 也无法用 表达.
证明: 有的 不存在于 中.
考虑前置码. 它从2位二进制开始, 其中一半用来表示, 另一半用来扩展.
例如,00, 10
用于表示,01, 11
衍生出010, 110
, 用于表示, 剩下的011, 111
继续衍生.
此时, 所有编码的最后一个数为0. 且长度大于等于2.
发现它不能用RE表示, 但是可以用表示. (用TH6.19容易得到)
DPDA and Ambiguity
对于DPDA表示的语言, 它一定有一个非二义性的语法.
但是, 非二义性的语法不一定能由DPDA来表达的. (可能只能用CFG / NPDA表达)
Ex: 可以用CFG : S -> 0S0 | 1S1 | epsilon
来表示. 这是非二义性的语法, 同时不能用DPDA表达. (这不是显然吗. 非二义性又不是DPDA独有的性质. )
总结: DPDA表达的语言是CFG表达语言的一个子集. 这个子集具有特殊的性质, 即, 一定存在一个非二义性的CFG来表达它.
但是, 对于存在非二义性CFG的语言, 它不一定能用DFDA表达. 因此箭头是单向的.
Equivalenve of PDA, CFG
- PDA和CFG是等价的
- 他们表示的是同一族语言:
CFL / Context Free Languages
- 就好像RE, DFA, NFAs表示的是同一族语言:
Regular Languages
- 他们表示的是同一族语言:
- 证明某个语言是CFL时, PDA很好用(例如, 对于括号平衡语言的证明)
CFG -> PDA
我们首先有 , 下面需要构造一个 , 使得 . (由于是非确定性PDA, 因此怎么样生成语言并不重要. )
构造过程: 对于P,
- 它只有一个状态
- 它的输入符号是G的终止符
- 它的栈符号是G的所有符号
- 它的起始符号是G的起始符.
工作过程: 从起始符开始, 不断接收一连串终止符的输入, 根据CFG的 production来完成栈的维护, 并最终将栈清空(如果输入的字符串可接受).
At each step, P represents some left-sentential form (step for a leftmost derivation)
- . 若输入的符号和栈顶符号都为终止符, 将终止符弹出. (不改变LSF)
- , 如果 在production中. (对于栈顶元素, 猜测每一种生成方式)
给定上面的结构后, 证明 for any x, if and only if
归纳证明:
only if: 对左边的生成步数做归纳. 当步数为0, 有, , 显然. 然后做链条. 链条时根据两个Rule, 分两种情况讨论.
if: 对右边, 左递推的生成过程步数做归纳. 和only if 的过程类似.
通过上面的证明, 我们令它的一个特殊情况, 就可以迅速得到 CFG与PDA的等价性. 于是, 我们证明了, CFG能够转换为等价的PDA
PDA -> CFG
虽然添加元素的数量是任意的, 但是每次弹出元素时, 至多只能弹出一个.
因此, 我们令G有这样一个变量 [pXq]
, 如果有一个cause P
, 令PDA恰好从p
转移到了q
, 且只弹出了元素 X
.
同时, 在进行P的过程中, 它永远不会 get below this X
(如果我们考虑的是某种"最小操作集")
显然对于起始元素
Z_0
和 , 它能生成一个变量[p_0 Z_0 q]
对于栈的元素集合, 它能够相应地生成一个变量和对应的字符串集合 (因为它如果想接收一个字符串, 那么它总要被弹出. )
那么显然, G的变量[pXq]
会且只会生成满足下面式子的符号
Production of G:
可以递归式地定义. 从状态p
开始, 栈顶元素为X
, 不断接收输入直到X恰好被弹出. 此时得到production
先考虑简单的情况:
case 1: 如果 , 那么[pXq] -> a
. a可以为空
case 2: 如果 , 那么[pXq] -> a[rYq]
.
case 3: 如果 , 那么[pXq] -> a[rYs][sZq]
, 对于所有的状态 s
. 因此, 生成了一族productions.
对于一般的生成式:
考虑包含在 中的式子 . 对于 (0, 1, 2的情况已经讨论)
生成如下的一族productions:
于是, 根据上面两个构造得到的结构, 可以证明 if and only if .
此处, p可以是任意状态, 所以和起始符号组合也得到一系列起始变量.
因此, 添加一个起始变量将这些状态吸收: