This repository was archived by the owner on May 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAssignment0227.v
More file actions
176 lines (153 loc) · 4.29 KB
/
Assignment0227.v
File metadata and controls
176 lines (153 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
Require Import Coq.Strings.String.
Require Import Coq.ZArith.ZArith.
Require Import Coq.micromega.Psatz.
Require Import SetsClass.SetsClass.
Require Import PV.Syntax.
Import Lang_SimpleWhile.
Require Import PV.DenotationalSemantics.
Import DntSem_SimpleWhile2 DntSem_SimpleWhile3 DntSem_SimpleWhile4.
Local Open Scope Z.
Local Open Scope sets.
Local Open Scope string.
(** 习题:*)
(** 下面的递归函数_[remove_skip]_定义了在程序语句中删除多余空语句的操作。*)
Fixpoint remove_skip (c: com): com :=
match c with
| CSeq c1 c2 =>
match remove_skip c1, remove_skip c2 with
| CSkip, _ => remove_skip c2
| _, CSkip => remove_skip c1
| _, _ => CSeq (remove_skip c1) (remove_skip c2)
end
| CIf e c1 c2 =>
CIf e (remove_skip c1) (remove_skip c2)
| CWhile e c1 =>
CWhile e (remove_skip c1)
| _ =>
c
end.
(** 下面请证明:_[remove_skip]_之后,确实不再有多余的空语句了。所谓没有空语句,
是指不出现_[c; SKIP]_或_[SKIP; c]_这样的语句。首先定义:局部不存在多余的空语
句。*)
Definition not_sequencing_skip (c: com): Prop :=
match c with
| CSeq CSkip _ => False
| CSeq _ CSkip => False
| _ => True
end.
(** 其次定义语法树的所有子树中都不存在多余的空语句。*)
Fixpoint no_sequenced_skip (c: com): Prop :=
match c with
| CSeq c1 c2 =>
not_sequencing_skip c /\
no_sequenced_skip c1 /\ no_sequenced_skip c2
| CIf e c1 c2 =>
no_sequenced_skip c1 /\ no_sequenced_skip c2
| CWhile e c1 =>
no_sequenced_skip c1
| _ =>
True
end.
(** 下面是需要证明的结论。*)
Theorem remove_skip_no_sequenced_skip: forall c,
no_sequenced_skip (remove_skip c).
Proof.
intro.
induction c; simpl; try tauto.
- destruct (remove_skip c1), (remove_skip c2);
simpl;
tauto.
Qed.
(** 习题:*)
(** 下面我们定义一项简单的程序变换:右结合变换。例如,将_[(c1;c2);c3]_变换为
_[c1;(c2;c3)]_。*)
(** 首先,这里定义一个辅助函数,该函数假设_[c]_与_[c0]_已经是右结合的,计算
_[c; c0]_转换后的结果*)
Fixpoint CSeq_right_assoc (c c0: com): com :=
match c with
| CSeq c1 c2 => CSeq c1 (CSeq_right_assoc c2 c0)
| _ => CSeq c c0
end.
(** 现在,可以在_[CSeq_right_assoc]_的基础上定义右结合变换_[right_assoc]_。*)
Fixpoint right_assoc (c: com): com :=
match c with
| CSeq c1 c2 =>
CSeq_right_assoc (right_assoc c1) (right_assoc c2)
| CIf e c1 c2 =>
CIf e (right_assoc c1) (right_assoc c2)
| CWhile e c1 =>
CWhile e (right_assoc c1)
| _ =>
c
end.
(** 下面证明:经过右结合变换后,确实程序语句中不再有左结合的结构了。下面分为两步
定义『无左结合结构』,即_[no_left_assoc]_。*)
Definition not_left_assoc (c: com): Prop :=
match c with
| CSeq (CSeq _ _) _ => False
| _ => True
end.
Fixpoint no_left_assoc (c: com): Prop :=
match c with
| CSeq c1 c2 =>
not_left_assoc c /\
no_left_assoc c1 /\ no_left_assoc c2
| CIf e c1 c2 =>
no_left_assoc c1 /\ no_left_assoc c2
| CWhile e c1 =>
no_left_assoc c1
| _ =>
True
end.
(** 证明也需要分两步进行。请先证明关于_[CSeq_right_assoc]_的引理。*)
Lemma CSeq_right_assoc_no_left_assoc: forall c c0,
no_left_assoc c ->
no_left_assoc c0 ->
no_left_assoc (CSeq_right_assoc c c0).
Proof.
intros.
induction c; try (simpl; tauto).
- destruct H, H1.
simpl.
tauto.
Qed.
(** 下面是需要证明的最终结论。*)
Theorem right_assoc_no_left_assoc: forall c,
no_left_assoc (right_assoc c).
Proof.
intro.
induction c; simpl; try tauto.
- apply CSeq_right_assoc_no_left_assoc; tauto.
Qed.
(** 习题:*)
Example skip_seq_skip:
eval_com (CSeq CSkip CSkip) == eval_com CSkip.
Proof.
simpl.
unfold seq_sem, skip_sem.
unfold_RELS_tac.
intros.
split; intro.
- destruct H, H.
rewrite H, H0.
reflexivity.
- exists a.
tauto.
Qed.
(** 习题:*)
Example inc_x_fact: forall s1 s2 n,
eval_com (CAsgn "x" [["x" + 1]]) s1 s2 ->
s1 "x" = n ->
s2 "x" = n + 1.
Proof.
intros.
unfold eval_com in H.
unfold asgn_sem in H.
destruct H.
rewrite H.
clear H.
simpl.
unfold add_sem, var_sem, const_sem.
rewrite H0.
reflexivity.
Qed.