-
Notifications
You must be signed in to change notification settings - Fork 1
/
tactics.v
345 lines (260 loc) · 7.54 KB
/
tactics.v
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
Set Implicit Arguments.
Unset Strict Implicit.
Module Tactics1.
Ltac ir := intros.
Ltac rw u := rewrite u.
Ltac rwi u h := rewrite u in h.
Ltac wr u := rewrite <- u.
Ltac wri u h := rewrite <- u in h.
Ltac ap h := apply h.
Ltac EasyAssumption :=
match goal with
| id1:(?X1 ?X2 ?X3 ?X4 ?X5 ?X6 ?X7 ?X8) |-
(?X1 ?X2 ?X3 ?X4 ?X5 ?X6 ?X7 ?X8) =>
exact id1
| id1:(?X1 ?X2 ?X3 ?X4 ?X5 ?X6 ?X7) |- (?X1 ?X2 ?X3 ?X4 ?X5 ?X6 ?X7) =>
exact id1
| id1:(?X1 ?X2 ?X3 ?X4 ?X5 ?X6) |- (?X1 ?X2 ?X3 ?X4 ?X5 ?X6) =>
exact id1
| id1:(?X1 ?X2 ?X3 ?X4 ?X5) |- (?X1 ?X2 ?X3 ?X4 ?X5) =>
exact id1
| id1:(?X1 ?X2 ?X3 ?X4) |- (?X1 ?X2 ?X3 ?X4) =>
exact id1
| id1:(?X1 ?X2 ?X3) |- (?X1 ?X2 ?X3) => exact id1
| id1:(?X1 ?X2) |- (?X1 ?X2) => exact id1
| id1:?X1 |- ?X2 => ap id1
| _ => fail
end.
Ltac am := solve [ EasyAssumption | assumption ].
Ltac au := first [ solve [ EasyAssumption ] | auto ].
Ltac eau := eauto.
Ltac tv := trivial.
Ltac sy := symmetry in |- *.
Ltac uf u := unfold u in |- *. Ltac ufi u h := unfold u in h.
Ltac ufa u := unfold u in *.
Ltac nin h := induction h.
Ltac CompareTac a b :=
assert (toclear : a = a); [ exact (refl_equal b) | clear toclear ].
Ltac UnfoldHead1 h :=
match constr:h with
| (?X1 ?X2) => unfold X1 in h
| _ => fail
end.
(*** we don't actually want to unfold certain things ***)
Ltac Good_Unfold g h :=
match constr:g with
| _ => unfold g in h
end.
Ltac Unfold_Head_R g h :=
match constr:g with
| (?X1 _ _ _ _ _ _ _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _ _ _ _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _ _ _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _ _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _ _) => Good_Unfold X1 h
| (?X1 _ _ _) => Good_Unfold X1 h
| (?X1 _ _) => Good_Unfold X1 h
| (?X1 _) => Good_Unfold X1 h
| ?X1 => Good_Unfold X1 h
end.
Ltac Unfold_Head h :=
match goal with
| id1:?X1 |- _ => CompareTac id1 h; Unfold_Head_R X1 h
| _ => fail
end.
Ltac Exploit h :=
match goal with
| id1:?X1 |- _ =>
CompareTac id1 h; assert X1; [ am | Unfold_Head h; Exploit h ]
| _ => idtac
end.
Ltac xlt h := Exploit h.
Definition DONE (A : Type) (a : A) := a.
Definition TODO (A : Type) (a : A) := a.
Ltac TodoAll :=
match goal with
| id1:?X1 |- _ =>
match constr:X1 with
| (TODO _) => fail
| _ => change (TODO X1) in id1; TodoAll
end
| _ => idtac
end.
Definition CheckProp (P : Prop) := P.
Ltac CheckPropTac P := assert (toclear : CheckProp P); [ am | clear toclear ].
Infix "&":= and (right associativity, at level 100).
Ltac Deconj :=
match goal with
| |- (and _ _) => ap conj; [ Deconj | Deconj ]
| |- (_ & _) => ap conj; [ Deconj | Deconj ]
| |- (and _ _) => ap conj; [ Deconj | Deconj ]
| |- (_ /\ _) => ap conj; [ Deconj | Deconj ]
| |- _ => au
end.
Ltac EasyDeconj :=
match goal with
| |- (and _ _) => ap conj; [ EasyDeconj | EasyDeconj ]
| |- (_ & _) => ap conj; [ EasyDeconj | EasyDeconj ]
| |- (and _ _) => ap conj; [ EasyDeconj | EasyDeconj ]
| |- (_ /\ _) => ap conj; [ EasyDeconj | EasyDeconj ]
| |- _ => idtac
end.
Ltac Expand :=
match goal with
| id1:(and ?X1 ?X2) |- _ =>
nin id1; Expand
| id1:(?X1 & ?X2) |- _ => nin id1; Expand
| id1:(and ?X1 ?X2) |- _ => nin id1; Expand
| id1:(?X1 /\ ?X2) |- _ => nin id1; Expand
| |- _ => Deconj
end.
(*** we write a tactic which is like Pose but which is anonymous ***)
Ltac Remind u :=
set (recalx := u);
match goal with
| recalx:?X1 |- _ => assert X1; [ exact recalx | clear recalx ]
end.
Ltac cp := Remind.
Ltac EasyExpand :=
match goal with
| id1:(and ?X1 ?X2) |- _ =>
nin id1; EasyExpand
| id1:(?X1 /\ ?X2) |- _ => nin id1; EasyExpand
| id1:(?X1 /\ ?X2) |- _ => nin id1; EasyExpand
| |- _ => EasyDeconj
end.
Ltac ee := EasyExpand.
Ltac xd := Expand.
Ltac PreExplode n :=
match constr:n with
| 0 => idtac
| (S ?X1) =>
match goal with
| id1:?X2 |- _ =>
CheckPropTac X2;
match constr:X2 with
| (DONE ?X3) => fail
| _ =>
assert (DONE X2);
[ unfold DONE in |- *; am
| Unfold_Head id1; EasyExpand; PreExplode X1 ]
end
| _ => idtac
end
end.
Ltac ClearDone :=
match goal with
| id1:(DONE ?X1) |- _ => unfold DONE in id1; ClearDone
| _ => idtac
end.
Ltac Exp := PreExplode 5; ClearDone.
Ltac Expl := PreExplode 10; ClearDone.
Ltac Explode := PreExplode 100; ClearDone.
Ltac CleanUp :=
match goal with
| id1:?X1,id2:?X1 |- _ => CheckPropTac X1; clear id2; CleanUp
| _ => idtac
end.
Ltac xde := Explode.
Ltac cx := Explode; CleanUp.
(***** we would like a general Cycle construction (can we parametrize tactics over tactics???) ***)
Ltac sh x := first
[ apply ex_intro with x
| apply ex_intro with x ].
Lemma seq_deconj : forall P Q : Prop, P -> (P -> Q) -> (P & Q).
ir. xd. Qed.
Ltac dj :=
match goal with
| |- (and ?X1 ?X2) => ap seq_deconj; ir; dj
| |- (?X1 & ?X2) => ap seq_deconj; ir; dj
| _ => idtac
end.
Ltac MiddleDeconj :=
match goal with
| |- (and _ _) =>
ap conj; [ MiddleDeconj | MiddleDeconj ]
| |- (_ /\ _) => ap conj; [ MiddleDeconj | MiddleDeconj ]
| |- (_ /\ _) => ap conj; [ MiddleDeconj | MiddleDeconj ]
| |- _ => first
[ solve [ trivial | EasyAssumption | sy; EasyAssumption ] | idtac ]
end.
Ltac MiddleExpand :=
match goal with
| id1:(and ?X1 ?X2) |- _ =>
nin id1; MiddleExpand
| id1:(?X1 /\ ?X2) |- _ => nin id1; MiddleExpand
| id1:(?X1 /\ ?X2) |- _ => nin id1; MiddleExpand
| |- _ => MiddleDeconj
end.
Ltac xe := MiddleExpand.
Definition type_of (T : Type) (t : T) := T.
Ltac Copy a :=
assert (type_of a);
[ exact a | match goal with
| id1:(type_of _) |- _ => ufi type_of id1
end ].
Ltac ufk a b := Copy b; ufi a b. Ltac uh a := red in a.
(*** replaces Unfold_Head a. as mentionned by Hugo ***)
Ltac uhg := red in |- *.
(*** Match Context With
[|-(?1 ? ? ? ? ? ? ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ? ? ? ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ? ? ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ? ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ? ?)] -> Unfold ?1 |
[|-(?1 ? ?)] -> Unfold ?1 |
[|-(?1 ?)] -> Unfold ?1 |
_-> Idtac.
***)
Ltac util a:=
match (type of a) with
| (?X1 -> ?X2 -> ?X3 -> ?X4 -> ?X5 -> ?X6) => assert X6; [apply a |idtac]
| (?X1 -> ?X2 -> ?X3 -> ?X4 -> ?X5) => assert X5; [apply a |idtac]
| (?X1 -> ?X2 -> ?X3 -> ?X4) => assert X4; [apply a |idtac]
| (?X1 -> ?X2 -> ?X3) => assert X3; [apply a |idtac]
| (?X1 -> ?X2) => assert X2; [apply a |idtac]
| _ => fail
end.
Lemma uneq : forall A B (f:A->B) x y,
x = y -> f x = f y.
Proof.
ir. rw H; tv.
Qed.
Lemma uneq2 : forall A B C (f : A -> B -> C) x x', x=x' -> forall y y', y=y' ->
f x y = f x' y'.
Proof.
ir. rw H. ap uneq. am.
Qed.
Ltac LookUpErasing :=
match goal with
| id1 : ?X1 |- _ =>
first [exact id1 | uh id1; ee; try tv; try am|clear id1 ]
| _ => fail
end.
Ltac lu :=
LookUpErasing; lu.
(*** not all that efficient for time so don't use too often ***)
End Tactics1.
Export Tactics1.
Module Utilities.
Lemma and_P : forall a b, and a b -> a.
Proof.
ir. nin H;am.
Qed.
Lemma and_Q : forall a b, and a b -> b.
Proof.
ir. nin H;am.
Qed.
Inductive PropGuard : Prop -> Prop :=
Pguard : forall P:Prop, P -> PropGuard P
.
Lemma PropGuard_use : forall P, PropGuard P -> P.
Proof.
ir. nin H. am.
Qed.
End Utilities. Export Utilities.