Skip to content

Commit 05f9c59

Browse files
committed
Add a clearer example of constructor backtracking
Fixes #17.
1 parent 6311a9a commit 05f9c59

File tree

1 file changed

+40
-14
lines changed

1 file changed

+40
-14
lines changed

src/Constructors.v

+40-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,44 @@ Inductive foo :=
33
| bar1
44
| bar2.
55

6+
Definition ctornum f :=
7+
match f with
8+
| bar0 => 1
9+
| bar1 => 2
10+
| bar2 => 3
11+
end.
12+
13+
(* an illustration of constructor backtracking *)
14+
Goal { f:foo | ctornum f = 3 }.
15+
unshelve eapply exist; [ constructor | match goal with
16+
| |- ?g => idtac g
17+
end; reflexivity ].
18+
Qed.
19+
20+
(* same as above, but more directly *)
21+
Definition foo_by_ctornum : {f:foo | ctornum f = 3}.
22+
Proof.
23+
(* the tactic after the ; works only because [constructor] backtracks until
24+
[reflexivity] succeeds. *)
25+
unshelve refine (exist _ _ _); [ constructor | reflexivity].
26+
Defined.
27+
28+
Inductive NumIsGood (n:nat) : Prop :=
29+
| Good0 (H: n = 0)
30+
| Good3 (H: n = 3)
31+
| Good7 (H: n = 7)
32+
.
33+
34+
Lemma three_is_good : NumIsGood 3.
35+
Proof.
36+
(* [constructor] on its own would pick [Good0], resulting in an unprovable
37+
goal. Adding [solve [ eauto ]] means the whole tactic backtracks on the choice
38+
of constructor. *)
39+
constructor; solve [ eauto ].
40+
Qed.
41+
42+
(* a fun but not very useful thing we can do with constructor backtracking is to
43+
print them out: *)
644
Ltac constructors t :=
745
let make_constructors :=
846
unshelve eapply exist;
@@ -15,20 +53,8 @@ Ltac constructors t :=
1553

1654
Goal True.
1755
constructors foo.
18-
(* bar0
56+
(* output:
57+
bar0
1958
bar1
2059
bar2 *)
2160
Abort.
22-
23-
Definition ctornum f :=
24-
match f with
25-
| bar0 => 1
26-
| bar1 => 2
27-
| bar2 => 3
28-
end.
29-
30-
Goal { f:foo | ctornum f = 3 }.
31-
unshelve eapply exist; [ econstructor | match goal with
32-
| |- ?g => idtac g
33-
end; reflexivity ].
34-
Qed.

0 commit comments

Comments
 (0)