Sipser CH2 PROBLEMS'ANSWER 2.43-2.50
2.43
没看懂,有待后续补充
2.44
构造PDA识别
, is start state : , , , ,
2.45
考虑
2.46
是由多个形似 的串拼接而成,考虑 ,有两个parse tree,故该语言ambiguous。 - 构造无二义的CFG关键在与消除
: - 证明无二义分两步:
- 证明
无二义,运用归纳法 - 证明
无二义,对于分解为 的串,有唯一最左推导
- 证明
2.47
形式化定义:
一个下推自动机
状态集
: : 初始状态,用于读取前半部分 。 : 开始读取后半部分 ,但尚未遇到 '1'。 : 在 中已经遇到了 '1'。 : 接受状态。
输入字母表
: 堆栈字母表
: ( 是初始堆栈符号) 初始状态:
初始堆栈符号:
接受状态集
: 转移函数
: - 读取前半部分
: 在 状态,每读入一个符号,就压入一个 。 对于任何 对于任何
- 猜测
和 的分割点: 非确定性地从 转换到 ,不消耗输入。 对于任何
- 读取
(未见 '1'): 在 状态,每读一个符号,弹出一个 。如果读到 '1',则进入 。 - 读取
(已见 '1'): 在 状态,继续读完 的剩余部分,每读一个符号弹出一个 。 - 接受: 当输入结束时,如果 PDA 处于
状态(表示已在 中见到'1')并且堆栈没有因为 而提前变空,则可以转换到接受状态。 对于任何
- 读取前半部分
这个 PDA 通过非确定性地猜测分割点,并利用堆栈来比较
设计一个生成
构造 CFG 的一个有效策略是,将语言
: 这可以通过在满足条件的字符串前添加任意字符来实现。 : 这是最基本的情况。
所以,我们可以设计一个产生核心字符串的文法,然后允许在这些字符串的左侧添加任意数量的字符。
: 在任何属于 的字符串前面添加一个 '0' 或 '1',新字符串仍然属于 。因为这会使 部分的长度加一,而 部分保持不变,所以 的条件仍然满足。 : 和 是基本情况,它们生成长度关系为 或 的字符串。
我们定义四组产生式:
: 生成偶数长度的字符串 ,其中 且 中有 '1'。 : 生成偶数长度的字符串 ,其中 且 中只有 '0'。 : 生成奇数长度的字符串 ,其中 且 中有 '1'。 : 生成奇数长度的字符串 ,其中 且 中只有 '0'。
思路: 我们从外向内生成字符串。例如,对于
文法规则: 令
- (解释:
规则表示,如果内部字符串的后半部分有 '1',则新字符串的后半部分也一定有 '1'。 规则表示,如果内部字符串的后半部分全是 '0',则右侧必须添加 '1'。 01 | 11
是最短的(长度为2)满足条件的基本情况。)
- (解释:
- (解释: 要想后半部分只包含 '0',右侧添加的必须是
'0',并且内部字符串的后半部分也必须只包含 '0'。
00 | 10
是基本情况。)
- (解释: 要想后半部分只包含 '0',右侧添加的必须是
'0',并且内部字符串的后半部分也必须只包含 '0'。
- (解释: 逻辑与
类似,但处理的是奇数长度的字符串。基本情况的长度为3。)
- (解释: 逻辑与
- (解释: 逻辑与
类似。基本情况的长度为3。)
- (解释: 逻辑与
这个 CFG 首先通过规则 (1) 确保了
2.48
- 构造PDA
, , 分别是1的前缀和后缀。 PDA:读 ,向栈压一个或两个 .读 ,弹出一个 PDA:读 ,向栈压一个 .读 ,弹出一个或两个
- 考虑字符
2.49
设
第一步:引入标记字母表
我们创建两个与
第二步:使用逆同态映射
定义一个同态 (homomorphism)
这个同态将标记过的符号映射回其原始形式。
现在,我们考虑语言
第三步:与正则表达式相交
考虑正则表达式
如果我们令
第四步:交换标记部分
现在,我们定义一个新语言
根据这个定理,由于
第五步:使用同态映射回原始字母表
最后,我们将语言
我们来分析
所以,
2.50
考虑