File: README.md

package info (click to toggle)
coq-libhyps 2.0.8-6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 304 kB
  • sloc: makefile: 14; sh: 7
file content (242 lines) | stat: -rw-r--r-- 7,779 bytes parent folder | download | duplicates (3)
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
This Library provides several coq tactics and tacticals to deal with
hypothesis during a proof.

Main page and documentation: https://github.com/Matafou/LibHyps

Demo file [demo.v](https://github.com/Matafou/LibHyps/blob/master/Demo/demo.v) acts as a documentation.

# Short description:

LibHyps provides utilities for hypothesis manipulations. In particular
a new tactic `especialize H` and a set of tacticals to appy or iterate
tactics either on all hypothesis of a goal or on "new' hypothesis after
a tactic. It also provide syntax for a few predefined such iterators.

## QUICK REF: especialize (BROKEN IN COQ-8.18)

This tactic is currently broken in coq v8.18. I am working on it. This
may need some work on coq side.

+ `especialize H at n [as h].` Creates a subgoal to prove the nth
    dependent premise of `H`, creating necessary evars for non
    unifiable variables. Once proved the subgoal is used to remove the
    nth premise of `H` (or of a new created hypothesis if the `as`
    option is given).

+ `especialize H at * [as h].` Creates one subgoal for each dependent
    premise of `H`, creating necessary evars for non unifiable
    variables. Once proved the subgoal is used to remove the premises
    of `H` (or of a new createdd hypothesis if the `as` option is
    given).

+ `especialize H until n [as h].` Creates one subgoal for each n first
    dependent premises of `H`, creating necessary evars for non
    unifiable variables. Once proved the subgoal is used to remove the
    premises of `H` (or of a new created hypothesis if the `as` option
    is given).

## QUICK REF: Pre-defined tacticals /s /n...

The most useful user-dedicated tacticals are the following

  + `tac /s` try to apply `subst` on each new hyp.
  + `tac /r` revert each new hyp.
  + `tac /n` auto-rename each new hyp.
  + `tac /g` group all non-Prop new hyp at the top of the goal.
  + combine the above, as in `tac /s/n/g`.
  + usual combinations have shortcuts: `\sng`, `\sn`,`\ng`,`\sg`...

# Install

## Quick install using opam

If you have not done it already add the coq platform repository to opam!

```bash
opam repo add coq-released https://coq.inria.fr/opam/released
```

and then:

```bash
opam install coq-libhyps
```

## Quick install using github:

Clone the github repository:

```bash
git clone https://github.com/Matafou/LibHyps
```
then compile:
```bash
configure.sh
make
make install
```

## Quick test:

```coq
Require Import LibHyps.LibHyps.
```

Demo files [demo.v](https://github.com/Matafou/LibHyps/blob/master/Demo/demo.v).

# More information

## Deprecation from 1.0.x to 2.0.x

  + "!tac", "!!tac" etc are now only loaded if you do: `Import
    LibHyps.LegacyNotations.`, the composable tacticals described
    above are preferred.
  + "tac1 ;; tac2" remains, but you can also use "tac1; { tac2 }".
  + "tac1 ;!; tac2" remains, but you can also use "tac1; {< tac2 }".

## KNOWN BUGS

Due to Ltac limitation, it is difficult to define a tactic notation
`tac1 ; { tac2 }` which delays `tac1` and `tac2` in all cases.
Sometimes (rarely) you will have to write `(idtac; tac1); {idtac;
tac2}`. You may then use tactic notation like: `Tactic Notation tac1'
:= idtac; tac1.`.

## Examples

```coq
Require Import LibHyps.LibHyps.

Lemma foo: forall x y z:nat,
    x = y -> forall  a b t : nat, a+1 = t+2 -> b + 5 = t - 7 ->  (forall u v, v+1 = 1 -> u+1 = 1 -> a+1 = z+2)  -> z = b + x-> True.
Proof.
  intros.
  (* ugly names *)
  Undo.
  (* Example of using the iterator on new hyps: this prints each new hyp name. *)
  intros; {fun h => idtac h}.
  Undo.
  (* This gives sensible names to each new hyp. *)
  intros ; { autorename }.
  Undo.
  (* short syntax: *)
  intros /n.
  Undo.
  (* same thing but use subst if possible, and group non prop hyps to the top. *)
  intros ; { substHyp }; { autorename}; {move_up_types}.
  Undo.
  (* short syntax: *)  
  intros /s/n/g.
  Undo.
  (* Even shorter: *)  
  intros /s/n/g.

  (* Let us instantiate the 2nd premis of h_all_eq_add_add without copying its type: *)
  (* BROKEN IN COQ 8.18*)
  (* especialize h_all_eq_add_add_ at 2.
  { apply Nat.add_0_l. }
  (* now h_all_eq_add_add is specialized *)
  Undo 6. *)
  Undo 2.
  intros until 1.
  (** The taticals apply after any tactic. Notice how H:x=y is not new
    and hence not substituted, whereas z = b + x is. *)
  destruct x eqn:heq;intros /sng.
  - apply I.
  - apply I.
Qed.
```

## Short Documentation

The following explains how it works under the hood, for people willing
to apply more generic iterators to their own tactics. See also the code.
  
### Iterator on all hypothesis

  + `onAllHyps tac` does `tac H` for each hypothesis `H` of the current goal.
  + `onAllHypsRev tac` same as `onAllHyps tac` but in reverse order
    (good for reverting for instance).


### Iterators on ALL NEW hypothesis (since LibHyps-1.2.0)

  + `tac1 ;{! tac2 }` applies `tac1` to current goal and then `tac2`
    to *the list* of all new hypothesis in each subgoal (iteration:
    oldest first).
    The list is a term of type `LibHyps.TacNewHyps.DList`. See the code.
  + `tac1 ;{!< tac2 }` is similar but the list of new hyps is reveresed.

### Iterators on EACH NEW hypothesis

  + `tac1 ;{ tac2 }` applies `tac1` to current goal and then `tac2` to
    each new hypothesis in each subgoal (iteration: older first).
  + `tac1 ;{< tac2 }` is similar but applies tac2 on newer hyps first.

  + `tac1 ;; tac2` is a synonym of `tac1; { tac2 }`.
  + `tac1 ;!; tac2` is a synonym of `tac1; {< tac2 }`.

### Customizable hypothesis auto naming system

Using previous taticals (in particular the `;!;` tactical), some
tactic allow to rename hypothesis automatically.

- `autorename H` rename `H` according to the current naming scheme
  (which is customizable, see below).

- `rename_all_hyps` applies `autorename` to all hypothesis.

- `!tac` applies tactic `tac` and then applies autorename to each new
  hypothesis. Shortcut for: `(Tac ;!; revert_if_norename ;;
  autorename).`.`

- `!!tac` same as `!tac` with lesser priority (less than `;`) to apply
  renaming after a group of chained tactics.

#### How to cstomize the naming scheme

The naming engine analyzes the type of hypothesis and generates a name
mimicking the first levels of term structure. At each level the
customizable tactic `rename_hyp` is called. One can redefine it at
will. It must be of the following form:

```coq
(** Redefining rename_hyp*)
(* First define a naming ltac. It takes the current level n and
   the sub-term th being looked at. It returns a "name". *)
Ltac rename_hyp_default n th :=
   match th with
   | (ind1 _ _) => name (`ind1`)
   | (ind1 _ _ ?x ?y) => name (`ind1` ++ x#(S n)x ++ y$n)
   | f1 _ ?x = ?y => name (`f1` ++ x#n ++ y#n)
   | _ => previously_defined_renaming_tac1 n th (* cumulative with previously defined renaming tactics *)
   | _ => previously_defined_renaming_tac2 n th
   end.

(* Then overwrite the definition of rename_hyp using the ::= operator. :*)
Ltac rename_hyp ::= my_rename_hyp.
```

Where:

- `` `id` `` to use the name id itself
- `t$n` to recursively call the naming engine on term t, n being the maximum depth allowed
- `name ++ name` to concatenate name parts.


#### How to define variants of these tacticals?

Some more example of tacticals performing cleaning and renaming on new
hypothesis.

```coq
(* subst or revert *)
Tactic Notation (at level 4) "??" tactic4(tac1) :=
  (tac1 ;; substHyp ;!; revertHyp).
(* subst or rename or revert *)
Tactic Notation "!!!" tactic3(Tac) := (Tac ;; substHyp ;!; revert_if_norename ;; autorename).
(* subst or rename or revert + move up if in (Set or Type). *)
Tactic Notation (at level 4) "!!!!" tactic4(Tac) :=
      (Tac ;; substHyp ;!; revert_if_norename ;; autorename ;; move_up_types).
```